简体   繁体   中英

How to correctly update state in array using react?

In a previous question , I was given an answer on how to update an array, which was achieved in the following way:

onClick(obj, index) {
  if (data.chosenBets[index]) {
    // Remove object.
    data.chosenBets.splice(index, 1);
  } else {
    // Add object.
    data.chosenBets.splice(index, 0, obj); 
  }
}

This does not trigger a re-render in my UI. How do I update the array (in the same way as above) while triggering a re-render?

Just mutating a state won't trigger re-render. You need to call setState() function:

// class component
onClick = () => {
  // update state
  this.setState(newState);
}

// functional component
...
  const [ state, setState ] = useState();

  ...

  setState(newState);

Also, it's quite important to perform immutable state updates since React relies on refs usually (especially, when using memo() or PureComponent ). So, it's better to create new instance of array with the same items.

onClick(obj, index) {
  let newData;
  if (data.chosenBets[index]) {
    newData = data.slice();
    newData.chosenBets.splice(index, 1);
  } else {
    newData = [ obj, ...data ]; 
  }

  setState(newData);
}

And you always can use some libraties for immutable update like immer , object-path-immutable etc.

Try avoiding impure functions when writing react codes. Here, splice is an impure method. I would recommend using the below code:

onClick(obj, index) {
  if (this.state.data.chosenBets[index]) {
    // Remove object.
    const data = {
        ...this.state.data,
        chosenBets: this.state.data.chosenBets.filter((cBet, i) => i !== index)
    };
    this.setState({ data });
  } else {
    // Add object.
    const data = {
        ...this.state.data,
        chosenBets: [ ...this.state.data.chosenBets, obj ]
    };
    this.setState({ data }); 
  }
}

I am assuming you have that array already saved in your state. Then you can do something like this:

onClick = (idx) => {
  let arr = [...this.state.arrayToModify];
  arr.splice(idx,1);
  this.setState({ arrayToModify: arr });
}

Hope this helps!

I needed to make a copy of the array:

let arr = appState.chosenBets
arr.splice(index, 1)
appState.chosenBets = arr

Rather than simply doing

data.chosenBets.splice(index, 1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM