1

I don't understand why a component only re-renders when using spread operator in an array state item as follows:

I first create a dynamic array state with false values:

const [openList, setOpenList] = React.useState(props.navBarItems.map((item, index) => false));

Option 1

function handleClick(index) {
       let newOpenList = [...openList]
       newOpenList[index] = !openList[index]
       console.log(newOpenList) // prints the same in both options
       setOpenList(newOpenList);

}

Option 2:

function handleClick(index) {
       let newOpenList = openList
       newOpenList[index] = !openList[index]
       console.log(newOpenList) // prints the same in both options
       setOpenList(newOpenList);
}

I used a console.log in render() (there's probably a better way to know if component updated using hooks) and it is only called when using option 1.

3
  • 2
    Option 2 will not cause a re-render because you're doing a state-mutation. ie:, you are not creating a new state object, and you are just making updates to the existing object in reference. Components only re-render when you provide a brand-new state, which is what you're doing with the spread operator. You're creating a brand-new array and then setting-state with that new array which is a valid state update. Commented Jul 16, 2019 at 4:30
  • In the second one, the new array is a modified version of the original. So when setState determines if it needs to rerender it sees that it’s the same object and doesn’t do anything Commented Jul 16, 2019 at 4:34
  • @ChristopherNgo you are right, the thing is that: "In JavaScript, arrays and objects are reference types. This means that when a variable is assigned an array or object, what gets assigned to the variable is a reference to the location in memory where the array or object was stored." freecodecamp.org/news/… Commented Jul 16, 2019 at 4:40

1 Answer 1

1

Because on option 2 you are mutating the openList array. When you do let newOpenList = openList you are not creating a new variable, you are just assigning openList to newOpenList. Even after adding one more item to newOpenList, when react compare the oldOpenList === openList this return true, and react does not update.

On option 1, when you do [...openList] it creates a new array with the same items of openList. As it will be a new variable, when react compares oldOpenList === openList it returns false, and react update.

You can have a more completed answer about that here

Sign up to request clarification or add additional context in comments.

1 Comment

You are right, the thing is that: "In JavaScript, arrays and objects are reference types. This means that when a variable is assigned an array or object, what gets assigned to the variable is a reference to the location in memory where the array or object was stored." freecodecamp.org/news/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.