执行componentDidMount后无法设置状态

时间:2018-10-18 20:15:15

标签: javascript reactjs asynchronous redux react-redux

我在组件上具有以下state变量和componentDidMount方法:

  state = {
    categorized_items: []
  }
  componentDidMount() {
    this.props.fetchItems()
    // I'm trying to do the following
    console.log('uncat_items: ', this.props.uncat_items)
    this.setState({categorized_items: this.props.uncat_items})
  }
  render () {....}

  function mapStateToProps({ items_reducer }) {
    return {
     uncat_items: items_reducer.uncat_items
    }
  }

this.props.fetchItems()操作方法可获取许多项并更新redux存储中的uncat_items(我可以在render / other中看到this.props.uncat_items变量的期望值方法没有任何问题)。但是,对于这种特殊情况,我需要做的是在执行fetchItems方法并更新商店中的uncat_items之后,我需要调用setState并更新{{ 1}}处于categorized_items状态。我知道在uncat_items方法中像这样调用this.setState是不正确的,但是我不知道该怎么做。如您所见,我尝试打印出componentDidMount,但返回一个空数组,即使它执行了action方法并在reducer中正确更新了。有人可以给我一个正确的方法吗?基本上,在执行this.props.uncat_items之后,使用更新后的redux存储中的特定变量设置状态。

2 个答案:

答案 0 :(得分:2)

您的代码中的问题是您先调用异步动作(this.props.fetchItems()),然后立即调用this.setState()-这在fetchItems请求完成之前(因此,在{{1 }}填充)。

假设您使用的是最新的React,根据您的特定用例,您可以:

1)放下状态,仅在渲染功能中直接使用props.uncat_items

2)由于使用了新道具,请使用this.props.uncat_items更新状态。

但是,如the docs所述,这并不是真正的建议,因为大多数情况下可以不同地处理(例如,如解决方案1所述,通过切换到受控组件)。可以在this article中找到更详细的说明,文档中也提到了这一点。

答案 1 :(得分:1)

您可以使用componentDidUpdate生命周期方法。看起来好像在安装组件时,商店可能仍包含该状态的默认值。然后,它会像您提到的那样在redux存储中正确更新,但组件状态不会更新。

要在组件收到新的道具后更新组件状态:

componentDidUpdate(prevProps){
  // compare prevProps to current props and update
  if(this.props.uncat_items !== prevProps.uncat_items) {
    this.setState({categorized_items: this.props.uncat_items})
    }
  }

正如评论中提到的那样,由于您不希望不必要地重新渲染组件,因此,直接在render方法中使用props是更理想的解决方案。