Javascript Can';t在未安装的组件上调用setState(或forceUpdate)

Javascript Can';t在未安装的组件上调用setState(或forceUpdate),javascript,reactjs,react-lifecycle,Javascript,Reactjs,React Lifecycle,我试图在组件更新后从服务器获取数据,但我无法做到这一点。据我所知,componentWillUnmount在组件即将被销毁时被调用,但我从来不需要销毁它,所以它对我来说毫无用处。解决这个问题的办法是什么?我应该什么时候设定状态 async componentDidUpdate(prevProps, prevState) { if (this.props.subject.length && prevProps.subject !== this.props.subject) {

我试图在组件更新后从服务器获取数据,但我无法做到这一点。据我所知,
componentWillUnmount
在组件即将被销毁时被调用,但我从来不需要销毁它,所以它对我来说毫无用处。解决这个问题的办法是什么?我应该什么时候设定状态

async componentDidUpdate(prevProps, prevState) {
  if (this.props.subject.length && prevProps.subject !== this.props.subject) {
    let result = await this.getGrades({
      student: this.props.id,
      subject: this.props.subject
    });
    this.setState({
      subject: this.props.subject,
      grades: result
    });
  }
}

async getGrades(params) {
  let response, body;

  if (params['subject'].length) {
    response = await fetch(apiRequestString.gradesBySubject(params));
    body = await response.json();
  } else {
    response = await fetch(apiRequestString.grades(params));
    body = await response.json();
  }

  if (response.status !== 200) throw Error(body.message);

  return body;
}
完全错误:

Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, 
but it indicates a memory leak in your application. To fix, cancel all subscriptions and
asynchronous tasks in the componentWillUnmount method.

我在本例中使用的一种常见模式是

componentWillUnmount() {
    this.isCancelled = true;
}
然后在等待异步函数解析的代码中,在设置状态之前添加一个检查:

async componentDidUpdate(prevProps, prevState) {
    if (this.props.subject.length && prevProps.subject !== this.props.subject) {
        let result = await this.getGrades({
            student: this.props.id,
            subject: this.props.subject
        });
        !this.isCancelled && this.setState({
            subject: this.props.subject,
            grades: result
        });
    }
}

这将停止对已卸载/正在卸载的组件的任何状态设置。接受的答案有效,并且是解决在组件呈现方法(getInitialState、componentWillMount、componentDidMount)中调用异步函数问题的有效方法


但更好的做法是使用状态管理助手,如Redux和Flux以及全局存储,这样可以避免多个集合状态的问题

我将放置一个断点(如果使用Chrome开发工具和sourcemaps),并查看何时调用setState,以及在
getGrades
解析为
result
之前是否卸载组件。对于调试,在探索相关组件时可能会有所帮助。显然,React正在销毁您的组件,因此»我的组件从未被销毁«似乎不是一个有效的假设。我没有意识到这一点。什么时候发生?谢谢你的建议。很少有人推荐我使用Redux,但我仍在学习过程中,因为我还没有读到关于Redux的文章,我仍然不确定什么时候应该使用它。在我学习了基础知识之后,我肯定会去看看。我也在一个类似的地方,我的建议来自于在Redux中实际看到了值,而有一个组件没有多次使用setState。学习起来有点奇怪,我自己还没有把它应用到实践中,但它确实很有价值。带有react的小型Web应用程序可能不需要redux,如果状态管理正确,则取决于组件/Web应用程序的大小。我不完全同意此评估。
Redux
的创建者表示,如果您确实想管理对整个应用程序有影响的信息,请使用
Redux
app state management。对于其他一切,使用常规异步调用(即fetch、axios等),而不管应用程序大小。简言之,使用不那么尴尬的东西。在我的情况下,来自异步调用的数据不值得redux存储,因此连接redux是一种过分的做法,因此原始答案的解决方案工作得最好这意味着React会抛出错误,因为它希望项目包含数据存储。我不太确定那是真的。