【问题标题】:"Print" string letter by letter in React在 React 中逐个字母“打印”字符串
【发布时间】:2021-04-20 10:02:49
【问题描述】:

我有一个 React Native 组件,它需要显示一个动画,其中一个字符串的字母一个字母一个字母地打印。所以,从逻辑上讲,我需要在一个循环中更新一个 React 状态钩子,以 1 秒的间隔将字符串的每个字符附加到它上面。到目前为止我所拥有的是:

let [placeholder, change_placeholder] = React.useState('');
const placeholder_print = () => {
    let temp = "Search for anything"
    console.log("Value of temp is now: " + temp)
    console.log("Length of string: " + temp.length)
    for (let i = 0; i < temp.length; i++) {
        console.log("Selected character is: " + temp.charAt(i))
        change_placeholder(placeholder.concat(temp.charAt(i)))
        console.log("Placeholder is now: " + placeholder)
    }
}

以及带有状态钩子的 React 组件:

<View>
    <Text>{placeholder}</Text>
</View>

是的,我知道这不会动画。但是在for 的末尾,placeholder 的值在逻辑上应该是字符串本身,对吧?如果是这样,我也许可以在 for 循环中使用 setTimeout() 绕过动画部分,以每秒运行一次。但是,这是placeholder_print() 运行时的输出:

[Fri Jan 15 2021 16:29:30.166]  LOG      Value of temp is now: Search
[Fri Jan 15 2021 16:29:30.168]  LOG      Length of string: 6
[Fri Jan 15 2021 16:29:30.169]  LOG      Selected character is: S
[Fri Jan 15 2021 16:29:30.170]  LOG      Placeholder is now:
[Fri Jan 15 2021 16:29:30.170]  LOG      Selected character is: e
[Fri Jan 15 2021 16:29:30.170]  LOG      Placeholder is now:
[Fri Jan 15 2021 16:29:30.171]  LOG      Selected character is: a
[Fri Jan 15 2021 16:29:30.171]  LOG      Placeholder is now:
[Fri Jan 15 2021 16:29:30.171]  LOG      Selected character is: r
[Fri Jan 15 2021 16:29:30.172]  LOG      Placeholder is now:
[Fri Jan 15 2021 16:29:30.172]  LOG      Selected character is: c
[Fri Jan 15 2021 16:29:30.172]  LOG      Placeholder is now:
[Fri Jan 15 2021 16:29:30.173]  LOG      Selected character is: h
[Fri Jan 15 2021 16:29:30.173]  LOG      Placeholder is now:

当在 Python 或什至没有状态挂钩的原生 JavaScript 中运行类似的逻辑时,这可以正常工作。我不知道这是否需要使用 React Native 中的 &lt;Animated&gt; 组件来实现,或者这是否是 React 状态挂钩工作方式的一些根本区别。我被困在这里,伸出援助之手会被投赞成票。

【问题讨论】:

    标签: javascript arrays reactjs string react-native


    【解决方案1】:

    您在 for 循环中看不到更新的原因是 setState() 是异步的,并且更新的状态值在 next 渲染之前不可用。所以你只是循环你的字符串,记录 current 状态值(这是一个空字符串),然后调用setState,一旦循环完成就会调用它。见:Console.log() after setState() doesn't return the updated state

    在 react 的上下文中考虑这样的循环时,您需要考虑更大的状态/渲染周期。动画的“循环”实际上是由状态变化触发的连续渲染。

    useEffect 钩子为您提供了一种利用此循环的内置方法,这意味着您只需通过顺序渲染跟踪index(sn-p 使用useRef 来保存值)并使用它来更新状态,从而触发新的渲染等。

    这是一个快速的 sn-p。

    const App = () => {
      const [placeholder, setPlaceholder] = React.useState('');
    
      const
        string = 'This is the final string.',
        index = React.useRef(0);
    
      React.useEffect(() => {
        function tick() {
          setPlaceholder(prev => prev + string[index.current]);
          index.current++;
        }
        if (index.current < string.length) {
          let addChar = setInterval(tick, 500);
          return () => clearInterval(addChar);
        }
      }, [placeholder]);
    
      return (
        <div>
          {placeholder}
        </div>
      )
    }
    
    
    ReactDOM.render(
      <App />,
      document.getElementById("root")
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
    
    <div id="root"></div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-16
      • 1970-01-01
      • 1970-01-01
      • 2011-10-17
      • 1970-01-01
      • 2022-12-20
      相关资源
      最近更新 更多