setState 不更新状态:ReactJS
[英] setState is not updating state: ReactJS
本文介绍了setState 不更新状态:ReactJS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我觉得我已经在阳光下尝试了一切,但一定遗漏了一些非常明显的东西.在下面的 addItem() 函数
中,我试图将一个新项目推入一个数组并更新状态,但无论我做什么,状态都不会从初始数组改变.
当我在 console.log newListItems 中包含新项目时,所以到目前为止一切正常,实际状态不会更新.我错过了什么?
addItem 方法:
addItem(text){var newListItems = this.state.listItems;newListItems.push(text);console.log(newListItems);this.setState = ({列表项:新列表项});}
我也没有在控制台中收到任何错误消息.
完整代码:
import React, { Component } from 'react';导入'./App.css';类 ListItem 扩展组件{使成为(){返回(<li>{this.props.title}</li>);}}类 AddItem 扩展组件{句柄点击(){this.props.addItem('等等');}使成为(){返回 (<div className="additem"><input type="text" className="newitemname"/><span className="btn" onClick={this.handleClick.bind(this)}>添加项目</span>
);}}类 App 扩展组件 {构造函数(道具){超级(道具);this.state = {listItems : ['洗碗','洗衣服','别的东西']};}添加项目(文本){var newListItems = this.state.listItems;newListItems.push(text);console.log(newListItems);this.setState = ({列表项:新列表项});}使成为() {返回 (<div className="应用程序"><ul>{this.state.listItems.map(function(item,index){返回 (<ListItem key={index} title={item}/>);})}<AddItem addItem={this.addItem.bind(this)}/>
);}}导出默认应用;
解决方案
问题是,您以错误的方式更新 state
,请使用:
this.setState({列表项:新列表项});
取而代之的是:
this.setState = ({列表项:新列表项});
原因:
因为 setState是一个函数而不是变量,我们需要调用它来更新状态值.
查看这个答案以了解有关setState 行为.
其他建议:
当你将任何array
赋值给任何变量时,变量只会得到array
的引用,意味着你将执行的所有更改,将直接应用于原始数组
.并且直接改变state
变量并不是一个好主意,所以首先使用slice
创建array
的副本,然后使用push
在其中添加项目.像这样:
var newListItems = this.state.listItems.slice();newListItems.push(text);this.setState({列表项:新列表项});
根据DOC:
<块引用>
永远不要直接改变 this.state,因为之后调用 setState() 可能替换您所做的突变.把 this.state 当作是不可变.
检查工作示例:
class ListItem extends React.Component{使成为(){返回(<li>{this.props.title}</li>);}}类 AddItem 扩展了 React.Component{句柄点击(){this.props.addItem(this.item.value);}使成为(){返回 (<div className="additem"><input type="text" ref={item =>this.item=item} className="newitemname"/><span className="btn" onClick={this.handleClick.bind(this)}>添加项目</span>
);}}类 App 扩展了 React.Component {构造函数(道具){超级(道具);this.state = {listItems : ['洗碗','洗衣服','别的东西']};}添加项目(文本){var newListItems = this.state.listItems.slice();newListItems.push(text);this.setState({列表项:新列表项});}使成为() {返回 (<div className="应用程序"><ul>{this.state.listItems.map(function(item,index){返回 (<ListItem key={index} title={item}/>);})}<AddItem addItem={this.addItem.bind(this)}/>
);}}ReactDOM.render(, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script><div id='app'/>
I feel like I've tried everything under the sun here but must be missing something very obvious. In the addItem() function
below, I am trying to push a new item into an array and update state, but no matter what I do state just won't change from the initial array.
When I console.log newListItems the new item is included, so everything up to that point is working, it's the actual state that won't update. What am I missing?
addItem Method:
addItem(text){
var newListItems = this.state.listItems;
newListItems.push(text);
console.log(newListItems);
this.setState = ({
listItems : newListItems
});
}
Also i am not getting any error message in console.
Full Code:
import React, { Component } from 'react';
import './App.css';
class ListItem extends Component{
render(){
return (<li>{this.props.title}</li>);
}
}
class AddItem extends Component{
handleClick(){
this.props.addItem('blah');
}
render(){
return (
<div className="additem">
<input type="text" className="newitemname"/>
<span className="btn" onClick={this.handleClick.bind(this)}>Add item</span>
</div>
);
}
}
class App extends Component {
constructor(props){
super(props);
this.state = {
listItems : ['Wash the dishes','Do the laundry','Something else']
};
}
addItem(text){
var newListItems = this.state.listItems;
newListItems.push(text);
console.log(newListItems);
this.setState = ({
listItems : newListItems
});
}
render() {
return (
<div className="App">
<ul>
{this.state.listItems.map(function(item,index){
return (
<ListItem key={index} title={item} />
);
})}
</ul>
<AddItem addItem={this.addItem.bind(this)} />
</div>
);
}
}
export default App;
解决方案
Issue is, you are updating the state
in a wrong way, Use this:
this.setState({
listItems : newListItems
});
Instead of this:
this.setState = ({
listItems : newListItems
});
Reason:
Because setState is a function not a variable, we need to call that to update the state values.
Check this answer for more details about setState behaviour.
Other Suggestions:
When you assign any array
to any variable, variable will only get the reference of array
, means all the changes that you will perform, will directly applied on the original array
. And its not a good idea to mutate the state
variable directly, so first create the copy of the array
by using slice
, then use push
to add the item in that. Like this:
var newListItems = this.state.listItems.slice();
newListItems.push(text);
this.setState({
listItems : newListItems
});
As per DOC:
Never mutate this.state directly, as calling setState() afterwards may
replace the mutation you made. Treat this.state as if it were
immutable.
Check the working example:
class ListItem extends React.Component{
render(){
return (<li>{this.props.title}</li>);
}
}
class AddItem extends React.Component{
handleClick(){
this.props.addItem(this.item.value);
}
render(){
return (
<div className="additem">
<input type="text" ref={item => this.item=item} className="newitemname"/>
<span className="btn" onClick={this.handleClick.bind(this)}>Add item</span>
</div>
);
}
}
class App extends React.Component {
constructor(props){
super(props);
this.state = {
listItems : ['Wash the dishes','Do the laundry','Something else']
};
}
addItem(text){
var newListItems = this.state.listItems.slice();
newListItems.push(text);
this.setState({
listItems : newListItems
});
}
render() {
return (
<div className="App">
<ul>
{this.state.listItems.map(function(item,index){
return (
<ListItem key={index} title={item} />
);
})}
</ul>
<AddItem addItem={this.addItem.bind(this)} />
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app' />
这篇关于setState 不更新状态:ReactJS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!