我正在尝试在React组件中创建打字效果。我传入一个字符串数组,并尝试在某个时间间隔后逐个字符地呈现它们(使用setTimeout)。下面是我的代码
state = {
typeColor: {
color: "blue"
},
typed: ""
};
componentDidMount() {
this.props.typewriter.map(string => {
console.log("1", string);
return this.stringChecker(string);
});
}
typeWriter(string) {
if (string.length === 0) {
return;
}
console.log("3", string);
this.setState((state, props) => ({ typed: state.typed.concat(string[0]) }));
console.log(this.state.typed);
setTimeout(() => this.typeWriter(string.slice(1)), 120);
}
stringChecker(string) {
console.log("2", string);
if (string === "Qurram") {
this.setState({ typeColor: { color: "blue" } });
} else {
this.setState({ typeColor: { color: "pink" } });
}
this.typeWriter(string);
}
render() {
return <div style={this.state.typeColor}>{this.state.typed}</div>;
}
}
现在,我希望它的执行流程是这样的:string数组的第一个元素在map函数中被'selected'-〉i call stringchecker for that first element -〉i call typewriter for that first element,并遍历字符。然后我返回到map函数并为next做同样的事情。看起来流程根本不是这样的,相反,它在每个字符片的两个字符串之间交替。如果有人能给我解释一下我会很感激的。非常感谢
沙盒链接:https://codesandbox.io/s/morning-dust-18nq5
4条答案
按热度按时间qlfbtfca1#
您可以简单地使用
useEffect()
钩子,它将在每次重新呈现(随机延迟)后增加文本的可见部分(存储在组件的状态中),直到整个文本被删除。您可以在下面找到此概念的现场演示:
e5nqia272#
输入逻辑是好的,但是,注意setTimeout是异步的,所以它不会等待整个单词被输入后再切换到下一个单词。解决方案是使整个输入流程异步,这样您就不会在前一个单词输入之前切换到下一个单词。
下面是sandbox demo:https://codesandbox.io/s/boring-greider-824nd
主要的变化是这样的:
检查我们是否完成了输入一个单词,然后将其切片,以获得下一个单词。如果我们还有单词,我们调用
typeWord
,其中包含应该输入的单词和接下来应该输入的单词数组。如果没有剩余的单词,我们退出键入。wooyq4lh3#
是的,
setTimeout()
在处理需要同步执行的任务时可能会很棘手(比如打字效果)。下面是使用
async/await
的另一种方法。我将typeWriter
方法设置为异步,因此它只会在字符串中的所有字符都被键入后返回。之后,将允许键入NEXT字符串。要实现这一点,stringChecker
也需要异步。检查一下,让我知道如果有什么困惑。https://codesandbox.io/s/youthful-davinci-d5bk5?fontsize=14&hidenavigation=1&theme=dark
另外......如果你只是想让它运行起来,我做了一个TypeIt,一个JS类型库,还有一个React组件版本。如果有用,请查看:
https://github.com/alexmacarthur/typeit-react
j8yoct9x4#
这对我很有效,我写的一个小的自定义钩子