I'm trying to make a typewriting effect in a React component. I pass in an array of strings and try to render them character by character after some interval (using setTimeout). Here is my code for that
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>;
}
}
Now I was expecting the execution flow of this to go like this: first element of string array is 'selected' in the map function -> i call stringchecker for that first element -> i call typewriter for that first element, and iterate over the characters. then i go back to the map function and do the same for next. It seems the flow is not like this at all,instead it alternates between the two strings for each character slice. I'd really appreciate if someone could explain that to me. Thank you very much
Sandbox link : https://codesandbox.io/s/morning-dust-18nq5
The typing logic is good, however, note that setTimeout is async, so it doesn't wait for the whole word to be typed before switching to the next one. The solution is to make the whole typing flow async, so you don't switch to the next word before the previous one has been typed.
Here's the sandbox demo: https://codesandbox.io/s/boring-greider-824nd
The main change is this one:
if (string.length === 0) {
words = words.slice(1);
words[0] && this.typeWord(words[0], words);
}
Check if we finished typing a word, then slice it, to get the next word. If we still have words we call typeWord
with the word that should be typed and the array of words that should be typed next. If there are no words left, we exit typing.