skip to Main Content

I literally took 4 hours to debug this in React JS. I am sharing a simplified code to reproduce the same scenario. The following code is a state variable and its setter function; Have a look at it:

const [arr, setArr] = useState([]);
setArr(prevArr => {
        prevArr.push(10);
        return prevArr;
})

The above code is supposed to add 10 into the state variable arr. But, it just adds 10 two times into the array. So, after the setArr worked, the new value of arr is [10, 10].
I spent 4 hours to check if there were leaks in useEffect (that I am using in my code), or something else, until I found that the following code works as intended:

setArr(prevArr => {
        return [...prevArr, number];
})

Can anyone explain me this behaviour? Also, are there any similar cases that I might experience in future as a react developer?

2

Answers


  1. Array.push() method pushes the object passed in as a parameter into the same reference of the original array. Whereas, when using a spread operator it creates a new array with a copy of the old array.
    Let’s understand this example:

    return [...prevArr, number];
    

    Here, we’re returning a value like this: [] which indicates JS to create a new array, then we’re spreading the entries of previous array using the spread operator: [...prevArr] which indicates to copy all the entries of prevArr into this newly created array, and finally passing a new value: [...prevArr, number] will add a new element in the array apart from the other copied elements.

    Login or Signup to reply.
  2. if you use prevArr.push and return prevArr, it means the array object is still old one.

    so react will bailout this state, meaning don’t trigger rerender on this situation.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search