setState 不更新状态:ReactJS

IT技术 reactjs
2021-03-23 07:19:01

我觉得我在这里的阳光下尝试了一切,但一定遗漏了一些非常明显的东西。addItem() function下面,我试图将一个新项目推送到一个数组中并更新状态,但无论我做什么,状态都不会从初始数组中改变。

当我 console.log newListItems 包含新项目时,所以到目前为止一切都在工作,它是不会更新的实际状态。我错过了什么?

addItem 方法:

addItem(text){
    var newListItems = this.state.listItems;
    newListItems.push(text);
    console.log(newListItems);

    this.setState = ({
        listItems : newListItems
    });

}

我也没有在控制台中收到任何错误消息。

完整代码:

1个回答

问题是,您state以错误的方式更新,请使用:

this.setState({
    listItems : newListItems
});

取而代之的是:

this.setState = ({
    listItems : newListItems
});

原因:

因为setState是一个函数而不是一个变量,我们需要调用它来更新状态值。

检查此答案以获取有关setState 行为的更多详细信息

其他建议

当您将 any 分配array给任何变量时,变量只会获得 的引用array,这意味着您将执行的所有更改都将直接应用于原始array. state直接改变变量并不是一个好主意,所以首先array通过 using创建 的副本slice,然后使用push在其中添加项目。像这样:

var newListItems = this.state.listItems.slice();
newListItems.push(text);
this.setState({
     listItems : newListItems
});

根据DOC

永远不要直接改变 this.state,因为之后调用 setState() 可能会替换你所做的改变。将 this.state 视为不可变的。

检查工作示例:

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' />

我还会slice()在之后添加一个调用var newListItems = this.state.listItems,以防有人切换到纯渲染。
2021-05-22 07:19:01
我的天啊。一个等号让我把头发拉了一个小时!感谢现场!
2021-05-30 07:19:01