我有一个 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
从逻辑上讲应该是字符串本身,对吧?如果是这样,我也许可以绕过动画部分setTimeout()
在 for 循环内每秒运行一次。但是,这是当placeholder_print()
is run:
[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 中运行类似的逻辑时,这工作得很好。我不知道这是否需要与<Animated>
React Native 中的组件,或者 React 状态钩子的工作方式是否存在一些根本差异。我被困在这里,伸出援助之手将会得到支持。
您在 for 循环中看不到更新的原因是setState()
是异步的,并且更新的状态值直到next使成为。所以你只是循环你的字符串,记录current状态值(这是一个空字符串),然后调用setState
循环完成后将被调用。看:setState() 之后的 Console.log() 不返回更新后的状态 https://stackoverflow.com/questions/54713510/console-log-after-setstate-doesnt-return-the-updated-state
在 React 上下文中考虑这样的循环时,您需要考虑更大的状态/渲染周期。动画的“循环”实际上是由状态变化触发的连续渲染。
The useEffect
hook 为您提供了利用此周期的内置方法,这意味着您只需跟踪index
通过顺序渲染(该片段使用useRef
保存值)并使用它来更新状态,从而触发新的渲染等。
这是一个快速片段。
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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)