skip to Main Content

I found this exercise on this site; I was testing this since I’m also just learning hooks in React.

I’m not able to understand why when you go to put a name identical to those already present in the array, the execution of useEffect stops.

Shouldn’t it skip the repeated name and then continue with the next ones? Or am I doing something wrong?

let users = ['Oliver', 'Thomas', 'George', 'George', 'William']
export default function App() {
  const [index, setIndex] = useState(0);
  console.log('RENDER');
  useEffect(() => {
    setTimeout(() => setIndex(index => index + 1), 1000)
    console.log('Hello ' + users[index]);
    console.log('Side Effect RUNS!');
    if (index === users.length - 1) {
      return
    }
  }, [users[index]])
}

2

Answers


  1. Side Effects in a Loop: The way you’re using setTimeout and setIndex inside the useEffect can potentially lead to unexpected behavior. The useEffect is executed after every render, and using the index state directly inside the setTimeout callback could cause issues since closures capture the state value at the time the callback is created.

    Accessing Elements of the Array: You’re trying to access elements of the users array using the index, but due to the asynchronous nature of the useEffect and the delay, you might go out of bounds of the array.

     const [index, setIndex] = useState(0);
    
      useEffect(() => {
        console.log('RENDER');
        console.log('Side Effect RUNS!');
        
        if (index >= users.length) {
          return;
        }
    
        const timeoutId = setTimeout(() => {
          console.log('Hello ' + users[index]);
          setIndex(index + 1);
        }, 1000);
    
        return () => clearTimeout (timeoutId);
      }, [index]);
    
    Login or Signup to reply.
  2. Your condition if (index === users.length – 1) is never met because index is not being incremented beyond 2 due to the repeated name. This causes the effect to get stuck in a loop where it’s repeatedly logging ‘Hello George’ without progressing to the next index.

    If you want to avoid this behavior and proceed to the next name even if it’s a repeat, you should increment the index regardless of whether the value matches or not. You can modify your useEffect like this:

    useEffect(() => {
      setTimeout(() => setIndex(index => index + 1), 1000);
    }, [index]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search