30 Mar 2025

I was working on a project that required cycling through an array of words and displaying them one at a time. Sounds simple. Show a word, wait a few seconds, show the next — and loop it forever.
My instinct? A loop. That’s always been my go-to when iterating over arrays — like a trusty six-shooter at my side.
But this time, nothing was firing properly. I’ve never been super confident with JavaScript timing functions like setTimeout or setInterval, but I knew this problem lived there. 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 often misunderstood setInterval.
Those three didn’t just wrangle my problem — they changed the whole corral.
My first instinct was to use forEach. I thought I could loop through the words and delay each one using setTimeout. In theory, this should’ve worked:
const words = ['Innovate', 'Elevate', 'Create'];
words.forEach((word) => {
setTimeout(() => {
console.log(word);
}, 2000);
});This approach worked once — and then stopped. No loop. No reactivity. No way to update the UI properly in React.
After realizing that forEach and setTimeout weren’t going to cut it, I turned to setInterval. I knew it ran a block of code every X milliseconds, but I’d never used it confidently inside a React component.
setInterval(() => {
console.log('This runs every 2 seconds');
}, 2000);Simple enough — but in React, we don’t just log things. We update state. So I wrapped the interval inside useEffect and tracked the current index with useState.
const [index, setIndex] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setIndex((prevIndex) => prevIndex + 1);
}, 2000);
return () => clearInterval(interval);
}, []);Every two seconds, state updated, React re-rendered, and the UI changed. Sweet! But there was still a problem… what happens when the index reaches the end of the array?

The index just kept climbing forever and eventually crashed the app. Arrays don’t appreciate being asked for words[1000]. What I needed was a way to loop back to the beginning.
That’s when the modulo operator (%) strolled in, tipped its hat, and said: I’ll take it from here.
const nextIndex = (prevIndex + 1) % words.length;This single line increments the index and resets it to 0 when it reaches the end of the array. Simple math. Perfect loop.
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);
}, []);
{words[index]}This was one of those moments where I had to unlearn what I thought I knew. I wanted to reach for a loop because loops feel natural with arrays — but React and time-based updates play by different rules.
The real solution came from combining a state callback, the modulo operator to create a loop, and setInterval to drive timing.
Moral of the story? If an array walks into a bar… don’t automatically pull a loop on ’em.