简体   繁体   English

如何使用反应正确更新阵列中的 state?

[英]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.这不会在我的 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.仅仅改变 state 不会触发重新渲染。 You need to call setState() function:您需要调用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 ).此外,执行不可变的 state 更新非常重要,因为 React 通常依赖于 refs(尤其是在使用memo()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.而且您总是可以使用一些库来进行不可变更新,例如immerobject-path-immutable等。

Try avoiding impure functions when writing react codes.在编写 React 代码时尽量避免使用不纯函数。 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.我假设您已经将该数组保存在 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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