Reactjs 如何使用从promise获得的信息设置组件的状态,以避免react中的内存泄漏

Reactjs 如何使用从promise获得的信息设置组件的状态,以避免react中的内存泄漏,reactjs,asynchronous,promise,state,Reactjs,Asynchronous,Promise,State,我应该在哪里设置组件的状态,以及从已解决的承诺中获得的信息,以确保如果在最后两个操作完成之前卸载组件,不会导致内存泄漏 class Schedule extends Component { constructor(props) { super(props); this.state = { someKey: '' }; } someMethod = () => { axios.get('some-url') .then((re

我应该在哪里设置组件的状态,以及从已解决的承诺中获得的信息,以确保如果在最后两个操作完成之前卸载组件,不会导致内存泄漏

class Schedule extends Component {
  constructor(props) {
    super(props);
    this.state = {
      someKey: ''
    };
  }

  someMethod = () => {
    axios.get('some-url')
    .then((response) => {
      setState({someKey: response})
    })
  }

  render(){
    return(
      <button onClick={this.someMethod}>Click Me</button>
    )
  }

}

export Schedule
类调度扩展组件{
建造师(道具){
超级(道具);
此.state={
someKey:'
};
}
someMethod=()=>{
get('some-url')
。然后((响应)=>{
setState({someKey:response})
})
}
render(){
返回(
点击我
)
}
}
出口时间表
如果我在设置新状态之前离开页面,If将显示以下错误:

'无法对已卸载的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。'


如何处理此问题?

一般来说,要处理API调用,我建议您使用一些应用程序状态管理F.E Redux/MobX。但对于简单的用例,您可以尝试使用:

class App extends Component {
      constructor(props) {
        super(props);
        this.isMounted = false;

        this.state = {
          someKey: []
        };
      }

      componentDidMount() {
        this.isMounted = true;
      }

      someMethod = () => {
        axios.get("some_url").then(res => {
          if (this.isMounted) {
            this.setState({
              someKey: res
            });
          }
        });
      };

      componentWillUnmount() {
        this.isMounted = false;
      }

      render() {
        ...
      }
    }

一般来说,为了处理API调用,我建议您使用一些应用程序状态管理F.E Redux/MobX。但对于简单的用例,您可以尝试使用:

class App extends Component {
      constructor(props) {
        super(props);
        this.isMounted = false;

        this.state = {
          someKey: []
        };
      }

      componentDidMount() {
        this.isMounted = true;
      }

      someMethod = () => {
        axios.get("some_url").then(res => {
          if (this.isMounted) {
            this.setState({
              someKey: res
            });
          }
        });
      };

      componentWillUnmount() {
        this.isMounted = false;
      }

      render() {
        ...
      }
    }

请注意,您也可以取消axios请求

类应用程序扩展组件{
建造师(道具){
超级(道具);
this.source=axios.CancelToken.source();
此.state={
someKey:[]
};
}
someMethod=()=>{
get(“some_url”{cancelToken:this.source.token})。然后(res=>{
这是我的国家({
someKey:res
});
})
//捕获axios取消错误,我们不想显示它
.catch(错误=>{
//如果不是axios取消错误,我们可能希望重新抛出错误(取决于应用程序结构)
如果(!err.name=='Cancel'){
犯错误;
}
});
};
组件将卸载(){
此.source.cancel('cancel message');
}
render(){
...
}
}

请注意,您也可以取消axios请求

类应用程序扩展组件{
建造师(道具){
超级(道具);
this.source=axios.CancelToken.source();
此.state={
someKey:[]
};
}
someMethod=()=>{
get(“some_url”{cancelToken:this.source.token})。然后(res=>{
这是我的国家({
someKey:res
});
})
//捕获axios取消错误,我们不想显示它
.catch(错误=>{
//如果不是axios取消错误,我们可能希望重新抛出错误(取决于应用程序结构)
如果(!err.name=='Cancel'){
犯错误;
}
});
};
组件将卸载(){
此.source.cancel('cancel message');
}
render(){
...
}
}

请显示调用
someMethod
done@vencovsky的位置。setState是否使用
此。您可以将
作为静态变量添加到
计划
类中,将
添加到
构造函数
中的集合中,并从
组件willunmount()
中的集合中删除
,然后确保每次从承诺解析调用
setState()
时,集合中都有
this
。请显示调用
someMethod
done@vencovsky的位置您是否使用
this.setState
?您可以将
set
作为静态变量添加到
Schedule
类中,将
this
添加到
constructor
中的集合中,并从
componentWillUnmount()
中的集合中删除
this
,然后确保每次调用
setState()时集合中都有
this
来自承诺决议。与我在评论中的建议非常相似:)我更喜欢这个,而不是我在评论中的建议。与我在评论中的建议非常相似:)我更喜欢这个,而不是我的建议。你可能希望在一个空的
.catch(()=>{})中捕捉取消
至少这样它不会产生未捕获的承诺拒绝(或者如果已经进行了错误处理,则集成它以区分错误响应和取消)。对,我编辑了我的响应以包含您的备注。您可能希望在一个空的
.catch(()=>{})中捕获取消
至少这样它不会产生一个未预料到的承诺拒绝(或者如果已经进行了错误处理,则集成它以区分错误响应和取消)。对,我编辑了我的响应以包含您的评论。