Lucas Guilleminot
Lucas Guilleminot

Reputation: 109

React does not render new states at their updates

When updating a state, react does not re-render the screen. Moreover, the use effect is not called.

enter image description here

When clicking on the "change" button, react does not seem to want to re-render with the new values. Also, the use effect is not called.

const [identity, setIdentity] = useState([{id: 1, name: "Lucas"}, {id: 2, name: "Jean"}]);
const [show, setShow] = useState(false);

useEffect(() => {
  console.log("UPDATE");
}, [identity]);

But when another state changes, the screen is updated.

You can try this CodeSandBox: https://codesandbox.io/s/nifty-frog-su3m30?file=/src/App.js

I have a hunch, maybe I'm not using the right method to change the value of my object.

function handleChange(evt) {
    const toEdit = identity;
    const index = toEdit.findIndex(predicate => predicate.id = 1);
    toEdit[index] = {...toEdit[index], name: "Michel"}
    console.log({index, toEdit});
    setIdentity(toEdit);
}

Upvotes: 1

Views: 48

Answers (2)

Lucas Guilleminot
Lucas Guilleminot

Reputation: 109

As @DBS and @secan said, I got confused with the state update.

This code works :

 function handleChange(evt) {
    const toEdit = [...identity]; // this line
    const index = toEdit.findIndex(predicate => predicate.id = 1);
    toEdit[index] = {...toEdit[index], name: "Michel"}
    console.log({index, toEdit});
    setIdentity(() => toEdit);
  }

When I create my copy, I have to create a new table (with the spread operator for example).

Thanks !

Upvotes: 0

Drew Reese
Drew Reese

Reputation: 203532

The issue here is state mutation with toEdit[index] = {...toEdit[index], name: "Michel"}. toEdit is a reference to the existing state identity.

function handleChange(evt) {
  const toEdit = identity;
  const index = toEdit.findIndex(predicate => predicate.id = 1);
  toEdit[index] = {...toEdit[index], name: "Michel"}
  console.log({index, toEdit});
  setIdentity(toEdit);
}

Use a functional state update to access and update from the previous state value. Map the previous state to a new array and create a new object reference for the identity object you are updating.

function handleChange(evt) {
  setIdentity(identity => identity.map(el => el.id === 1 ? {
    ...el,
    name: "Michel"
  } : el));
}

Edit react-does-not-render-new-states-at-their-updates

Upvotes: 2

Related Questions