0

My problem: Want to display every letter after 1 second, but instead of this I display all the letters immediately. I have tried many ways to do this but still can't.

My code:

const [parrot, setParrot] = useState({ content: ' ' });

const displayText = () => {
    let text = 'Parrot';
    let freeLetters = [...text];
    let sumOfLetters = [];

    for (let k = 0; k < freeLetters.length; k++) {
        (function() {
            let j = k;
            setTimeout(() => {
                sumOfLetters.push(freeLetters[j]);
                console.log(sumOfLetters);
                setParrot({
                    content: sumOfLetters.join(' ')
                });
                console.log(parrot.content);
            }, 1000);
        })();
    }
};
   return (
    <div className={classes.contentwrapper}>
        <h1 onClick={() => displayText()}>Click me, {parrot.content}</h1>
    </div>
);
Claudio Cortese
  • 1,372
  • 2
  • 10
  • 21

2 Answers2

1

Your timeouts are all set to 1000 milliseconds, you should multiply the timeout by the current index of the loop.

What you need to do is increase the setTimeout wait value on each iteration of your loop. See a working example below.

const [parrot, setParrot] = useState({ content: ' ' });

const displayText = () => {
    let text = 'Parrot';
    let freeLetters = [...text];
    let sumOfLetters = [];

    for (let k = 0; k < freeLetters.length; k++) {
        (function() {
            let j = k;
            setTimeout(() => {
                sumOfLetters.push(freeLetters[j]);
                console.log(sumOfLetters);
                setParrot({
                    content: sumOfLetters.join(' ')
                });
                console.log(parrot.content);
            }, 1000 * (j + 1));
            // j + 1 because the loop starts at 0. 
            // For the second iteration this will be 2000 ms
            // For the third, 3000 ms
            // Etc.
        })();
    }
};
   return (
    <div className={classes.contentwrapper}>
        <h1 onClick={() => displayText()}>Click me, {parrot.content}</h1>
    </div>
);
Lee Brindley
  • 6,242
  • 5
  • 41
  • 62
0

You're loop is just firing off an function that says in 1000ms do something. The loop will just continue to iterate and until the condition meets and then in your 1000ms, all of the setTimeouts will trigger almost back to back. You could either use the setInterval or maybe rewrite this to use a recursion loop based on some condition.