无法在卸载的组件上调用setState

时间:2018-06-09 13:23:10

标签: reactjs react-native

继续在React Native中收到以下错误消息,真的不明白它来自哪里

  

警告:无法在卸载时调用setState(或forceUpdate)   零件。这是一个无操作,但它表示你的内存泄漏   应用。要修复,请取消所有订阅和异步任务   在componentWillUnmount方法中。

我有以下简单的组件:

class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            isLoggedIn: false,
        } 
    }

    componentDidMount(){
        this.fetchToken()
      }

    async fetchToken(){
        const access_token = await AsyncStorage.getItem('access_token')
        if (access_token !== null) {
           this.setState({ isLoggedIn: true })
        }
    }

    render() {
        const login = this.state.isLoggedIn
        if (login) {
            return <NavigatorLoggedIn />
        } else { 
            return <Navigator/>
        }
    }

}

6 个答案:

答案 0 :(得分:0)

你可以使用它:

componentDidMount() {
    this.function()
}

function = async () => { 
    const access_token = await AsyncStorage.getItem('access_token')
    if (access_token !== null) {
        this.setState({ isLoggedIn: true })
    }
}

或者您可以在function中致电constructor

我希望这会对你有帮助......

答案 1 :(得分:0)

你需要使用isMounted变量。

componentDidMount(){
  this.setState({ isMounted = true });
  const access_token = await AsyncStorage.getItem('access_token')
  if (access_token !== null && this.isMounted) {
     this.setState({ isLoggedIn: true })
  }
}

componentWillUnmount(){
   this.setState({ isMounted = false });
}

或者如果您使用Axios,则可以使用axios的取消请求功能 这里:https://github.com/axios/axios#cancellation

答案 2 :(得分:0)

可以了:

let self;

class App extends React.Component {
    constructor(props) {
        super(props)
        self = this;
        this.state = {
            isLoggedIn: false,
        } 
    }

    componentDidMount(){
        this.fetchToken()
      }

    async fetchToken(){
        const access_token = await AsyncStorage.getItem('access_token')
        if (access_token !== null) {
           self.setState({ isLoggedIn: true })
        }
    }

    render() {
        const login = self.state.isLoggedIn
        if (login) {
            return <NavigatorLoggedIn />
        } else { 
            return <Navigator/>
        }
    }

}

答案 3 :(得分:0)

对于我来说,我通过“ yarn start”或“ npm start”重新启动服务器来解决了该问题

答案 4 :(得分:0)

您可以尝试以下方法:

class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            isLoggedIn: false,
        } 
    }

    _isMounted = false;   

    componentDidMount(){
        this._isMounted = true; 
        this.fetchToken()
      }

    async fetchToken(){
        const access_token = await AsyncStorage.getItem('access_token')
        if (access_token !== null && this._isMounted) {
           this.setState({ isLoggedIn: true })
        }
    }

    componentWillUnmount() {
        this._isMounted = false;
    } 

    render() {
        const login = this.state.isLoggedIn
        if (login) {
            return <NavigatorLoggedIn />
        } else { 
            return <Navigator/>
        }
    }

}

通过使用_isMounted,仅在安装了组件的情况下才调用setState,而卸载不会等待异步调用完成。最终,当异步调用结束时,该组件已经卸载,因此无法设置状态。为此,答案仅是在设置状态之前检查组件是否已安装。

答案 5 :(得分:0)

取消所有异步操作是解决方案之一