skip to Main Content

I’m just studying React and in particular I’m studying the useEffect.

What I’m failing to figure out is why the useEffect is skipping me the last element of the array.

Can someone kindly explain to me why and how to fix it please?

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

}

3

Answers


  1. The if (index === users.length - 1) statement literally skips the last element.

    You can simply make it if (index >= users.length)

    Login or Signup to reply.
  2. because you return before you it you should do

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

    or you should

    if (index >= users.length)
    

    for the xisting code

    Login or Signup to reply.
  3. This is because you made a condition to return in useEffect, if the index is equal to the last element index:

    if (index === users.length - 1) {
        return
    }
    

    You need to make the if statement condition to return, if the index is greater than the last element index:

    // users.length equals (element last index + 1), since the first array index is 0
    if (index === users.length) {
        return;
    }
    

    This will make the function work.

    One last thing is that you need to clear the timeout to avoid memory leaks, and it may give you unexpected results sometimes.

    Here is the full code:

      let users = ['Oliver', 'Thomas', 'George', 'William']
      const [index, setIndex] = useState(0);
      console.log('RENDER');
      useEffect(() => {
    
        // returning if we passed last array index
        if (index === users.length) {
          return
        }
        // we named out timeout to be able to clear it
        const timer = setTimeout(() => setIndex(index => index + 1), 2000)
        console.log('Hello ' + users[index]);
        console.log('Side Effect RUNS!');
    
        // clearing the timeout to avoid anyproblems
        return () => {
          clearTimeout(timer);
        }
      }, [users[index]])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search