Marlow
Marlow

Reputation: 21

Can't call setState on an unmounted component

Keep getting the following error message in React Native, really don't understand where it is coming from

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.

I have the following simple component:

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/>
        }
    }

}

Upvotes: 2

Views: 10750

Answers (6)

Shawn Wang
Shawn Wang

Reputation: 2742

Cancel all the async operation is one of the solution

Upvotes: 0

user10942985
user10942985

Reputation:

You can try this:

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/>
        }
    }

}

By using _isMounted, setState is called only if component is mounted, The unmounting doesn't wait for the async call to finish. Eventually when the async call gets over, the component is already unmounted and so it cannot set the state. To do this, the answer simply does a check to see if the component is mounted before setting the state.

Upvotes: 0

Weijing Jay Lin
Weijing Jay Lin

Reputation: 3238

For me, I resolved it by restart the server by "yarn start" or "npm start"

Upvotes: -1

san
san

Reputation: 1693

you need use isMounted variable.

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 });
}

Or if you use Axios, you can use cancel request feature of axios this here: https://github.com/axios/axios#cancellation

Upvotes: 0

Ho&#224;ng Vũ Anh
Ho&#224;ng Vũ Anh

Reputation: 677

It's will be work:

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/>
        }
    }

}

Upvotes: 0

Ali SabziNezhad
Ali SabziNezhad

Reputation: 3118

You can use it:

componentDidMount() {
    this.function()
}

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

Or you can call function in constructor.

I hope this will help you...

Upvotes: 2

Related Questions