无法在已卸载的组件上执行React状态更新。 (类组件)

时间:2020-02-24 11:15:25

标签: javascript react-native setstate

问题

我正在用React Native编写应用程序,但无法解决此特定警告。我了解这是由对数据的请求引起的,但是在请求完成之前会卸载组件。 Also, i have applied some solutions found here,但无法正常使用。这是我的代码,我也已经在下面应用了解决方案。

class PeopleScreen extends React.Component {

      constructor(props) {
        super(props);
        this.state = {
          listData : [ ]
        };
    
      }
  
      componentDidMount() {
        // Get list of people.
        AsyncStorage.getItem("people",
          function(inError, inPeople) {
            if (inPeople === null) {
              inPeople = [ ];
            } else {
              inPeople = JSON.parse(inPeople);
            }
            this.setState({ listData : inPeople });
          }.bind(this)
        );
    
      };
   
      render() { return (
      )

这是我已应用的解决方案:

 class PeopleScreen extends React.Component {
    _isMounted = false;

      constructor(props) {

        super(props);

        this.state = {
          listData : [ ]
        };

      }

      componentDidMount() {
        this._isMounted = true;

        // Get list of people.
        AsyncStorage.getItem("people",
          function(inError, inPeople) {
            if (inPeople === null) {
              inPeople = [ ];
            } else {
              inPeople = JSON.parse(inPeople);
            }
            this.setState({ listData : inPeople });
          }.bind(this)
        );

      };

      componentWillUnmount() {
        this._isMounted = false;
      }

      render() { return ( 

      )

此外,请查看错误: my error here

2 个答案:

答案 0 :(得分:0)

您需要使用if语句包装setState,以检查_isMounted的值是否为真

if(this._isMounted) {
  this.setState({ listData : inPeople });
}

答案 1 :(得分:0)

我觉得这里的异步代码可能有问题。您的回调看起来不错,并且从技术上讲应该可以,但是我建议您尝试将回调重写为Promise resolution

最重要的是,您还可以通过消除多余的if/else来通过以下方式改进代码,但这更多是出于美观方面的考虑。

AsyncStorage.getItem('people').then(async (value) => {
  let inPeople = value ? JSON.parse(value) : [];
  this.setState({ listData : inPeople });
  // or even a one-liner: this.setState({ listData : value ? JSON.parse(value) : [] });
});