React: setInterval Not working after one interval

My Goal:

I’m trying to build a component that when you give it props.items and props.fadeEvery, it will act as a text rotator. I eventually want it to fade in an out, but I’m having trouble with my window.setInterval.

Possible Issue:

I’m calling setIndex in the useEffect hook, but is that not good practice? How an I have it iterate through the array items infinitely?

TextFade.tsx

// Imports: Dependencies
import React, { useState, useEffect } from 'react';

// TypeScript Type: Props
interface Props {
  items: Array<string>,
  fadeEvery: number,
};

// Component: Text Fade
const TextFade: React.FC<Props> = (props): JSX.Element => {
  // React Hooks: State
  const [ index, setIndex ] = useState<number>(0);

  // React Hooks: Lifecycle Methods
  useEffect(() => {
    const timeoutID: number = window.setInterval(() => {
      // End Of Array
      if (index > props.items.length) {
        // Set Data
        setIndex(0);
      }
      else {
        // Set Data
        setIndex(index + 1);
      }
    }, props.fadeEvery * 1000);

    // Clear Timeout On Component Unmount
    return () => window.clearTimeout(timeoutID);
  }, []);

  return (
    <div id="text-fade-container">
      <p id="text-fade-text">{props.items[index]}</p>
    </div>
  );
};

// Exports
export default TextFade;

Answer

Your index values are taken from initital closure and it won’t update unless useEffect callback is called again. You can instead use functional way to update state

useEffect(() => {
    const timeoutID: number = window.setInterval(() => {
      // End Of Array 
      setIndex(prevIdx => {
         if (prevIdx > props.items.length) {
            // Set Data
             return 0;
         }
         else {
           // Set Data
           return prevIdx + 1;
          }
      })
      
    }, props.fadeEvery * 1000);

    // Clear Timeout On Component Unmount
    return () => window.clearTimeout(timeoutID);
  }, []);