I'm creating a DoS-like typing effect dialogue for my website. I've got the effect running but it seems to skip the second render of the loop.
I've got an effect hook that adds each letter from a string to a new state via an index ref until the index ref equals the length of the string. Here's that (and a stackblitz of it);
const startingLine = `Lorem ipsum.`;
const [screenResponse, setScreenResponse] = useState('');
const [skipDialogue, setSkipDialogue] = useState(false);
let index = useRef(0);
useEffect(() => {
let addChar;
function tick() {
setScreenResponse((prev) => prev + startingLine[index.current]);
index.current++;
console.log(screenResponse);
}
if (index.current < startingLine.length - 1 && !skipDialogue) {
addChar = setInterval(tick, 500);
return () => clearInterval(addChar);
} else {
setScreenResponse(startingLine);
}
}, [screenResponse, skipDialogue, startingLine]);
The screenResponse is what shows on screen, except the 'o' from 'Lorem' would be missing until the effect is finished (and is still missing without the else line).
I've taken it out of React.StrictMode, and it happens in all string lengths except one, and happens no matter how long the interval takes.
I need the startingLine.length - 1 so that it doesn't drop an undefined at the end, but removing that doesn't change the missing second render.
With the console.log in the tick interval, it doesn't print 'Lo' just straight to 'Lr'. So, why is the second render being skipped and how can I fix it?
