【问题标题】:Why React SetState is not working as expected?为什么 React SetState 没有按预期工作?
【发布时间】:2019-10-02 06:57:15
【问题描述】:

我的 React 组件中有这段代码: (__loadItems() 返回一个 Promise。)

componentDidMount(){
    const self=this;
    this.__loadItems().then((itemsCollection) => {
        // below will log what I expect:
        console.log('itemsCollection', itemsCollection);

        self.setState( (state, props) => {


             return {
                 itemTypes: itemsCollection,
             };
        }, () => {
        //below will contain what expected
        console.log(self.state.itemTypes);
        //ISSUE: state.itemTypes will be Array(0)
        console.log(self.state);

        // });
    });
}

为什么我的状态 itemTypes 不会按预期设置?

 console.log(self.state)

将输出:

 { itemTypes: Array(0)}

【问题讨论】:

  • setState 不能那样工作。试试self.setState({ itemTypes: itemsCollection}, () => { //... })
  • setState 确实以这种方式工作 - 但是,如果您不与现有状态合并,其他字段将被删除。您确定itemsCollections 包含数据吗?
  • 是的,第一个日志确实打印了预期的数据。你说的合并是什么意思?它不应该合并 setState 返回的内容吗?
  • setState 是异步的,如果您想在新状态更改后通过控制台记录新状态,您必须执行类似 self.setState({itemTypes:itemsCollection},()=>{console.log(self.state)}) 的操作
  • 事实上我在回调部分检查状态。但是状态仍然不是我所期望的

标签: arrays reactjs promise


【解决方案1】:

这对我来说只是简单的工作,我没有看到问题。回调还会记录项目。

const loadItems = () => (
  new Promise(resolve => {
    setTimeout(() => resolve(['item1', 'item2']), 1500);
  })
)

class App extends React.Component { 
  state = { items: [] };
  
  componentDidMount(){
    loadItems().then(items => this.addItemsToState(items))
  }
  
  addItemsToState = items => {
    this.setState({ items }, console.log(items))
  }
  
  render() {
    const { items } = this.state;
    return <ul>{items.map(item => <li>{item}</li>)}</ul>
  }
}

ReactDOM.render(<App />, document.getElementById('root'));

  
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

【讨论】:

    【解决方案2】:

    问题与控制台日志本身有关。 我使用的是 Google chrome,似乎打印的 console.log json 对象的预览是 指加载前的初始状态。使用空数组:

      { itemTypes: Array(0)}
    

    我没有尝试扩展此预览,因为 Array(0) 我希望里面什么也看不到。

    尽管声明了 Array(0),但通过扩展所需的有效负载响应仍然存在。

    棘手且令人困惑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-04
      • 2021-01-03
      • 2018-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多