Javascript 无法在执行componentDidMount后设置状态

Javascript 无法在执行componentDidMount后设置状态,javascript,reactjs,asynchronous,redux,react-redux,Javascript,Reactjs,Asynchronous,Redux,React Redux,我的组件上有以下状态变量和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({categori

我的组件上有以下
状态
变量和
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()
action方法获取大量项并更新redux存储中的
uncat_项
(我可以在render/other方法中看到
this.props.uncat_项
变量的预期值,没有任何问题)。但是,对于这种特殊情况,我需要做的是在执行
fetchItems
方法并更新存储中的
uncat\u项目之后,我需要调用
setState
并在状态为
uncat\u项目
时更新
categorized\u项目。我知道在
componentDidMount
方法中这样调用
this.setState
是不正确的,但我不知道怎么做。正如您所看到的,我尝试打印出
this.props.uncat_items
,但这返回了一个空数组,即使它执行了action方法并在reducer中正确更新。有人能给我一个正确的方法吗?基本上,在执行了componentDidMount之后,使用更新的redux存储中的特定变量设置状态。

您可以使用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})
    }
  }

如评论中所述,在渲染方法中直接使用道具是更理想的解决方案,因为您不希望组件不必要地重新渲染。

您可以使用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})
    }
  }

如注释中所述,在呈现方法中直接使用道具是更理想的解决方案,因为您不希望组件不必要地重新呈现。

代码中的问题是,您调用异步操作(
this.props.fetchItems()
),然后立即调用
this.setState()
-这发生在
fetchItems
请求完成之前(因此,在
props.uncat\u items
填充之前)

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

1) 删除状态并直接在渲染函数中使用
this.props.uncat_items

2) 使用静态getDerivedStateFromProps
更新由于新道具而产生的状态


但是,如中所述,并不建议这样做,因为大多数情况下可以采用不同的处理方式(例如,如解决方案#1中所述,通过切换到受控组件)。在中可以找到更长的描述,文档中也提到了这一点。

代码中的问题是,您调用了一个异步操作(
this.props.fetchItems()
),然后立即调用
this.setState()
——这发生在
fetchItems
请求完成之前(因此,在填充
props.uncat_项之前)

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

1) 删除状态并直接在渲染函数中使用
this.props.uncat_items

2) 使用静态getDerivedStateFromProps
更新由于新道具而产生的状态


但是,如中所述,并不建议这样做,因为大多数情况下可以采用不同的处理方式(例如,如解决方案#1中所述,通过切换到受控组件)。在中可以找到更长的描述,文档中也提到了这一点。

您的
console.log()
生成了一个空数组,因为它不是异步调用;它在
fetchItems()返回任何数据之前执行。(如果
fetchItems()
返回一个承诺,您可以很容易地修复它。)为什么不直接在渲染函数中使用
this.props.uncat_items
(或者在任何您想使用
this.state.categorized_items
)呢?除非您需要编辑单独的数据副本,最好的做法是不要把你的道具复制到你的州。相反,您可以在
渲染
函数中使用条件渲染,如
返回this.props.uncat_items.length>0
    ..
:没有项

您的
控制台.log()
生成了一个空数组,因为它不是异步调用;它在
fetchItems()返回任何数据之前执行。(如果
fetchItems()
返回一个承诺,您可以很容易地修复它。)为什么不直接在渲染函数中使用
this.props.uncat_items
(或者在任何您想使用
this.state.categorized_items
)呢?除非您需要编辑单独的数据副本,最好的做法是不要把你的道具复制到你的州。相反,您可以在
渲染
函数中使用条件渲染,如
返回this.props.uncat_items.length>0
    ..
:无项目

我不会说这是一个最佳解决方案,因为这将触发组件的另一个重新招标。理想情况下,道具应根据react文档直接使用。尽管向op演示为什么道具和状态在组件生命周期的实例中不是他所期望的是很有用的。我不会说这是一个最佳解决方案,因为这将触发组件的另一个重新招标。理想情况下,道具应该按照react文档直接使用。尽管向op演示为什么道具和状态不是他在comp实例中所期望的是有用的