Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

State not update inside setInterval in React useEffect

I am creating a bot to auto generate text when component is mounted, but I have a problem when setInterval in useEffect. As my expected, I want to concate each word from the string in an sample text and update it into state until everything is done but my code not works, I only get a first word Hello in screen. What I am wrong and how I can resolve this problem?

const sampleText = 'Hello my customer, how can I help you?';

const [conversation, setConversation] = useState([]);

useEffect(() => {
    let i = 0;

    const textToArray = sampleText.split(' '); 

    const newText = [...conversation];

    // create initialization state for the first time
    if (newText.length < 1) {
        newText.push({
            id: Math.random(),
            reply_as: 'bot',
            message: '',
        });
    }

    // begining to generate bot message to reply
    const timer = setInterval(() => {
        if (i < textToArray.length) {
            // concate a message property in latest item with each string in newText array
            newText[newText.length - 1].message += textToArray[i];
            setConversation(newText);
        } else {
            clearInterval(timer);
        }

        i++;
    }, 300);

    return () => clearInterval(timer);
}, []);

return (
   <div className="message-list">
      {conversation.map(item => (             
         <div>
            <span>Sender: {item.reply_as}</span>
            <p>{item.message}</p>
         </div>
      ))}
   </div>
)

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

You need to provide a new array reference, otherwise React doesn’t re-render the component.

setConversation([...newText]);

The first setConversation triggered a re-render, that’s why "Hello" was shown, but the following calls to setConversation didn’t trigger a re-render because the array reference stayed the same.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading