javascript 如何在 React 中使用 setState() 来清空/清除数组的值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29994296/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use setState() in React to blank/clear the value of an array
提问by JZ.
I am trying to clear an array, but I'm having trouble.
this.setState({warnErrorTypes:[]})
我正在尝试清除数组,但遇到了麻烦。
this.setState({warnErrorTypes:[]})
I'm not sure if I am dealing with a race condition, or what the specific issue is, but I can see that the value of my array is consistently wrong in the case that I need to reset its value to [].
我不确定我是否正在处理竞争条件,或者具体问题是什么,但我可以看到我的数组的值在我需要将其值重置为 [] 的情况下始终是错误的。
How does one replace an array that contains [1,2] with [] then subsequently [3] where the following are true:
如何将包含 [1,2] 的数组替换为 [] 然后是 [3] ,其中满足以下条件:
- this.state.warnErrorTypes is an Array which starts out with []
- Based on condition, 2 is pushed in Array
- Based on condition, 1 is pushed in Array.
- Based on condition, 3 is NOT pushed in Array
- Pause. User interacts with UI
- Array is blanked:
this.setState({warnErrorTypes:[]})
- Based on condition, 2 is NOT pushed in Array
- Based on condition, 1 is NOT pushed in Array
- Based on condition, 3 is pushed in Array.
- this.state.warnErrorTypes 是一个以 [] 开头的数组
- 根据条件,2 被推入 Array
- 根据条件,1 被推入数组。
- 根据条件,3 不会被推入数组
- 暂停。用户与 UI 交互
- 数组被清空:
this.setState({warnErrorTypes:[]})
- 根据条件,2 不会被推入数组
- 根据条件,1 不会被推入数组
- 根据条件,将 3 推入 Array。
The result of the logic above is always [2,1,3]
, when I expect it to be [3]
.
上面逻辑的结果总是[2,1,3]
在我期望的时候[3]
。
回答by Mike 'Pomax' Kamermans
setState
is atomic, so you can't just issue multiple setState() calls and expect things to work, you either have to wait for the state to update before updating it again, or shadow an instance variable.
setState
是原子的,所以你不能只发出多个 setState() 调用并期望事情能正常工作,你要么必须等待状态更新再更新它,或者隐藏一个实例变量。
Option 1:
选项1:
moo: function() {
this.setState({
myarr: []
}, function() { // called by React after the state is updated
this.setState({
myarr: [3]
});
});
}
This is fairly cumbersome. The other option is to use a "real" instance variable that you send over as state at moments when you need to.
这是相当麻烦的。另一种选择是使用“真实”实例变量,您可以在需要时将其作为状态发送。
Option 2:
选项 2:
getInitialState: function() {
this.mylist = [];
return {
myarr: this.mylist
};
},
...
moo: function() {
this.mylist = [];
for(var i=0; i<10; i++) {
this.mylist.push(i);
}
this.setState({ myarr: this.mylist });
}
Remember that updating the state means you have changed an aspect of your component that demands a rerender, so don't use setState if you don't intend the component to rerender, like between clearing the array and refilling it. Do that stuff separately, and only update the state once you're done.
请记住,更新状态意味着您已经更改了需要重新渲染的组件的一个方面,因此如果您不打算重新渲染组件(例如在清除数组和重新填充数组之间),请不要使用 setState。单独做这些事情,只有在完成后才更新状态。
Option 3:
选项 3:
You could also do this by taking out the state values, running your updates, and then rebinding, without ever building a persistant instance variable:
您也可以通过取出状态值,运行更新,然后重新绑定来完成此操作,而无需构建持久性实例变量:
moo: function() {
var list = this.state.myarr;
while(list.length > 0) { list.splice(0,1); }
for(var i=0; i<10; i++) { list.push(i); }
this.setState({ myarr: list });
}
The net effect is the same: you onlyupdate your UI when your data is in some stable configuration, so if you think you're calling setState()
more than once between renders, that's a problem: every setState()
call may trigger a render, and consecutive setState()
may "override" each other if you don't wait for them to bind first.
最终效果是一样的:只有在数据处于某种稳定配置时才更新 UI,因此如果您认为在setState()
两次渲染之间调用了多次,那就有问题了:每次setState()
调用都可能触发渲染,而连续调用可能setState()
会“如果您不等待它们先绑定,则相互覆盖”。
回答by joeytwiddle
Option 3, as mentioned by Anders Ekdahl:
选项 3,正如 Anders Ekdahl 所提到的:
moo () {
this.setState(state => ({
myarr: []
}));
// ...
if (weShouldAddAThree) {
this.setState(state => ({
myarr: [ ...state.myarr, 3 ] // like push but without mutation
}));
}
}
This pattern is useful if you need to refer to the previous existing state when you perform your state update. I'm not sure if you really need the previous state in your example, but I will explain this pattern as if you did.
如果您在执行状态更新时需要参考先前存在的状态,则此模式很有用。我不确定您是否真的需要示例中的先前状态,但我会像您一样解释这种模式。
The merge operation we provide to setState
is always applied asynchronously, at some point in the future, at React's discretion. When the setState()
function returns, our operation has not been applied, it has only been queued.
我们提供的合并操作setState
总是异步应用,在未来的某个时候,由 React 自行决定。当setState()
函数返回时,我们的操作还没有被应用,它只是在排队。
Therefore we should never use this.state
in our state updater, because that might be out of date: an old copy of the state. If we need to know the previous state, we should receive the state
argument in the function we pass to setState, and use that.
因此我们永远不应该this.state
在我们的状态更新器中使用,因为它可能已经过时了:状态的旧副本。如果我们需要知道之前的状态,我们应该state
在传递给 setState 的函数中接收参数,并使用它。
回答by leeCoder
You can as well use this to clear array without using setState:
您也可以使用它来清除数组而不使用 setState:
this.state.your_array.length = 0;