Reactjs 在不调用setState的情况下响应状态更新?
我正在用React制作一个待办事项列表应用程序。“我的状态”中有项目,也有已删除的项目,因此可以恢复这些项目:Reactjs 在不调用setState的情况下响应状态更新?,reactjs,Reactjs,我正在用React制作一个待办事项列表应用程序。“我的状态”中有项目,也有已删除的项目,因此可以恢复这些项目: state = { items: ['item 1', 'item 2', 'item 3'], deletedItems: ['item 4', 'item 5'] }; 因此,我的删除项函数必须从items状态删除该项,并将其置于deletedItems状态 removeItem(number) { const itemsState = this
state = {
items: ['item 1', 'item 2', 'item 3'],
deletedItems: ['item 4', 'item 5']
};
因此,我的删除项函数必须从items状态删除该项,并将其置于deletedItems状态
removeItem(number) {
const itemsState = this.state.items;
const deletedItemsState = this.state.deletedItems;
const itemToBeDeleted = itemsState[number];
deletedItemsState.push(itemToBeDeleted);
itemsState.splice(number, 1);
this.setState({ items: itemsState });
}
上面的代码可以工作,但我不明白为什么deletedItems状态在没有调用setState的情况下被更新。我不是在遵循最佳实践吗
我不是在遵循最佳实践吗
没有。问题在于,您没有像您可能相信的那样使用临时变量,而是直接变异deletedItems
。基本上:
const itemsState = this.state.items;
const deletedItemsState = this.state.deletedItems;
这些行不创建各自状态变量的副本,而是只创建对它们的引用
所以当你这么做的时候
deletedItemsState.push(itemToBeDeleted);
你正在直接改变状态!这是一个不,不,正如你可能已经知道的
为什么会发生这种情况?
要理解这一点,您必须了解基本值和复合值之间的赋值工作方式不同
例如:
var x = y;
如果y
是字符串、数字、布尔值、null或未定义,则x
将复制y
的值。但是,如果是对象,数组或函数x
将存储其引用
解决方案: 您需要做的是创建它们的浅拷贝。像这样:
const itemsState = this.state.items.slice();
const deletedItemsState = this.state.deletedItems.slice();
这将使itemsState
和deletedetemstate
分别从This.state.item
和This.state.deletedetems
中分离变量
演示: MyApp类扩展了React.Component{ 构造函数(){ 超级(); 此.state={ 项目:[“项目1”、“项目2”、“项目3”], deletedItems:[‘第4项’、‘第5项’] }; } removeItem=(数字)=>{ const itemsState=this.state.items; const deleteditemstate=this.state.deletedItems; const itemtobedelete=itemsState[number]; DeletedItemState.push(itemToBeDeleted); 项目状态拼接(编号1); 这是我的国家({ 项目:项目状态 }, () => { console.log(this.state); }); } render(){ 返回( 项目:
-
{this.state.items.map((item,i)=>
- {item}Remove )}
-
{this.state.deletedItems.map(item=>
- {item} )}
我不是在遵循最佳实践吗
没有。问题在于,您没有像您可能相信的那样使用临时变量,而是直接变异deletedItems
。基本上:
const itemsState = this.state.items;
const deletedItemsState = this.state.deletedItems;
这些行不创建各自状态变量的副本,而是只创建对它们的引用
所以当你这么做的时候
deletedItemsState.push(itemToBeDeleted);
你正在直接改变状态!这是一个不,不,正如你可能已经知道的
为什么会发生这种情况?
要理解这一点,您必须了解基本值和复合值之间的赋值工作方式不同
例如:
var x = y;
如果y
是字符串、数字、布尔值、null或未定义,则x
将复制y
的值。但是,如果是对象,数组或函数x
将存储其引用
解决方案: 您需要做的是创建它们的浅拷贝。像这样:
const itemsState = this.state.items.slice();
const deletedItemsState = this.state.deletedItems.slice();
这将使itemsState
和deletedetemstate
分别从This.state.item
和This.state.deletedetems
中分离变量
演示: MyApp类扩展了React.Component{ 构造函数(){ 超级(); 此.state={ 项目:[“项目1”、“项目2”、“项目3”], deletedItems:[‘第4项’、‘第5项’] }; } removeItem=(数字)=>{ const itemsState=this.state.items; const deleteditemstate=this.state.deletedItems; const itemtobedelete=itemsState[number]; DeletedItemState.push(itemToBeDeleted); 项目状态拼接(编号1); 这是我的国家({ 项目:项目状态 }, () => { console.log(this.state); }); } render(){ 返回( 项目:
-
{this.state.items.map((item,i)=>
- {item}Remove )}
-
{this.state.deletedItems.map(item=>
- {item} )}
这不是处理应用程序中状态更改的正确方法 比如说这条线,
const itemsState = this.state.items;
它创建一个变量itemsState,该变量指向this.state.items。因此,对itemsState所做的任何更改都将在state.items中更改。这会改变你的数据
最佳实践是使用库(如)进行状态更新,或者将状态对象克隆到变量中,然后对其执行突变。完成后,最后使用setState()更新状态
下面是一段代码片段,解释如何使用Object.assign()进行克隆。正如您在代码段中看到的那样,这不会更改原始状态变量
var状态={
项目:[“项目1”、“项目2”、“项目3”],
deletedItems:[‘第4项’、‘第5项’]
};
函数removeItem(编号){
const itemsState=Object.assign([],this.state.items);
const deleteditemstate=Object.assign([],this.state.deletedItems);
const itemtobedelete=itemsState[number];
DeletedItemState.push(itemToBeDeleted);
项目状态拼接(编号1);
//this.setState({items:itemsState});
console.log(状态);
}
移除项目(1)代码>这不是处理应用程序中状态更改的正确方法
比如说这条线,
const itemsState = this.state.items;
它创建一个变量itemsState,该变量指向this.state.items。因此,对itemsState所做的任何更改都将在state.items中更改。这会改变你的数据。