Component not re-rendering after change in an object state in React

Viewed 395

There are others Stack Overflow threads that are kind of related to this question but very briefly answered. I wanted to create one that would more explicitly treat the problem that occurs when changing a state that's an object.

In the below code I'm updating on click the firstName property of user object, which is a state, but nothing is happening. Why is that?

export default function App() {
  const [user, setUser] = useState({
    firstName: "Jhon",
    lastName: "Doe",
  });
  const changeFirstName = () => {
    const newUser = user;
    newUser.firstName = "David";
    setUser(newUser);
  };
  return (
    <div>
      <div>
        <p>First Name: {user.firstName}</p>
        <p>Last Name: {user.lastName}</p>
      </div>
      <button onClick={changeFirstName}>Change First Name</button>
    </div>
  );
}
1 Answers

React won't update the DOM every time you give the same state to a setState. For primitive values like Number, String, and Boolean, it's obvious to know wether we are giving a different value or not.

For referenced values like Object and Array in the other hand, changing their content doesn't flag them as different. It should be a different memory reference. See your commented code to understand what you are doing wrong:

const newUser = user;        // does a reference copy => newUser == user
newUser.firstName = "David"; // changes its content => newUser == user
setUser(newUser);            // at this point it's like nothing has changed

A solution could be the spread operator, will create a copy of your existing object but on a new memory reference, and then you overwrite the properties that you want to change:

const newUser = {...user};   // creates a copy of user on a new reference
newUser.firstName = "David"; // updates firstName field of it
setUser(newUser);            // new reference is given to setUser
Related