0

我正在尝试在我的 React 项目中制作自动文本动画。我可以让它在 VanillaJS 中工作,但我不知道如何在 React 中做到这一点。(我是 React 的初学者。)

import React, { Component } from 'react'

class AutoTextSection extends Component {
    writeText = () => {
       let idx = 1

       const text = "This is the text sentence."
       document.getElementById('auto-text').textContent = text.slice(0, idx)

       idx++

       if (idx > document.getElementById('auto-text').length) {
        idx = 1
    }

        setTimeout(this.writeText, 1000)
    }
    render() {
       return (
          <section id="auto-text-sec">
            <h2 className="text-light" id="auto-text">
            {this.writeText()}
            </h2>
          </section>
       )
    }
}
  

只是我能看到第一个字母。然后它向我抛出了这个错误:TypeError:无法将属性'textContent'设置为null。

4

1 回答 1

0

在反应中,您必须使用ref才能直接访问 DOM 元素。

更改您的代码:

import React, { Component } from 'react'

class AutoTextSection extends Component {
  constructor(props) {
    super(props);
    this.autoTextRef = React.createRef();
  }

  writeText = () => {
    let idx = 1

    const text = "This is the text sentence."
    this.autoTextRef.current.textContent = text.slice(0, idx)

    idx++

    if (idx > this.autoTextRef.current.length) {
      idx = 1
    }
    setTimeout(this.writeText, 1000)
  }

  render() {
    return (
      <section id="auto-text-sec">
        <h2 className="text-light" ref={this.autoTextRef}>
          {this.writeText()}
        </h2>
      </section>
    )
  }
}

在这一行中,您很可能想要使用位于 DOM 元素内的文本节点:

if (idx > this.autoTextRef.current.length) {

所以使用:

if (idx > this.autoTextRef.current.textContent.length) {

但是您的代码仍然包含错误。最好开始输入componentDidMount生命周期钩子。

另一个明显的问题是,当你调用 时writeText,你总是会有idx = 1;,因此,这个状态必须忍受得更高。您可以为此使用状态。

同样在代码中没有终止递归调用的条件。

最终的最小工作代码应如下所示:

import React, { Component } from 'react'

class AutoTextSection extends Component {
  constructor(props) {
    super(props);
    this.autoTextRef = React.createRef();
    this.state = {
      idx: 1,
    }
  }

  componentDidMount() {
    this.writeText()
  }

  writeText = () => {

    console.log('writeText')
    const text = "This is the text sentence."
    this.autoTextRef.current.textContent = text.slice(0, this.state.idx)

    this.setState((prev) => ({
      idx: ++prev.idx,
    }))

    if (this.state.idx <= text.length) {
      console.log('writeText recursion')
      setTimeout(this.writeText, 100)
    }
  }

  render() {
    return (
      <section id="auto-text-sec">
        <h2 className="text-light" ref={this.autoTextRef} />
      </section>
    )
  }
}
于 2021-05-08T20:47:35.053 回答