30 Mar 2025
I was working on a project that required me to cycle through an array of words and display them one at at time. Sounds simple.The goal was clear, show one word, wait a few seconds, show the next, and loop it FOREVER.My instinct… A LOOP! That has always been my go-to when iterating over an array, just like a trusty 6-shooter at my side.But this time, something wasn’t firing properly. I’ve never been super confident with JavaScript’s timing functions like setTimeout or setInterval, but I knew this is where I need to be for this timing function to work. As I dug deeper, I realized the tools I thought I needed weren’t the ones I actually needed, Enter: the callback function, the modulo operator, and the time-sensitive, often misunderstood setInterval.Those three didn’t just wrangle my problem, they went and changed the whole corral.
const words = ['Innovate', 'Elevate', 'Create'];
words.forEach((word, index) => {
setTimeout(() => console.log(word);
}, 2000);
});
This approach worked once and then it stopped. No loop. No reactivity. No way to update the UI properly in React.
setInterval(() => {
console.log('This runs every 2 seconds');
}, 2000);
Simple enough. But in React, we don’t just want to log something. We want to update the UI. That means updating state. So I wrapped the setInterval inside a useEffect, and used useState to keep track of which word should be showing:const [index, setIndex] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setIndex((prevIndex) => prevIndex + 1);
}, 2000);
return () => clearInterval(interval); // cleanup
}, [ ]);
Every 2 seconds, the state updated, React re-rendered, and I could display the new word. Sweet!But there was still a problem... What happens when the index reaches the end of the array?That’s when the modulo operator strolled in, tipped its hat, and said: 'I’ll take it from here, you yellow-belly...'
const nextIndex = (prevIndex + 1) % words.length;
This line does two things at once. Increments the index by 1 and Resets it to 0 if it reaches the end of the array. It’s a simple piece of math, but it keeps the app from crashing and creates a perfect loop. Once I plugged this into the setInterval callback, the cycle was complete. const words = ['Innovate', 'Elevate', 'Create', 'Accelerate'];
const [index, setIndex] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setIndex((prevIndex) => (prevIndex + 1) % words.length);
}, 2000);
return () => clearInterval(interval); // Cleanup on unmount
}, []);
{words[index]}