Set state in Ajax Call Back throws error: Warning: setState (...): can only update installed or mounted

I have a fairly simple react container component that tries to invoke set state in an ajax callback called from componentDidMount. Full error:

Warning: setState (...): Can only update mounted or mounted component. This usually means that you called setState () on an unmounted component. This is a non-op. Check the code of the UserListContainer component.

order of operations from my console.log:

render
child-render
componentDidMount
ajax-data
[Big ol Error Message]

      

I started using async / await, but when I got the error, I went back to callbacks with the same result. This is the relevant code:

    export class UserListContainer extends React.Component<any, any>
{

    constructor() {
        super();
        this.state = {
            users: [], request: {}
        };

    }
    //componentDidMount = async () => {
componentWillMount = () => {
        console.log('componentWillMount');
        //var response: Models.IUserQueryResponse = await Api.UserList.get(this.state.request);
        Api.UserList.get(this.state.request).then((response) => {
            console.log('ajax-data');
            if (response.isOk) {
                this.setState({ users: response.data, request: response.state });
            }
        });
    }
    render() {
        console.log('render');
        return <UserList
            request={this.state.request}
            users={this.state.users}
            onEditClick={this.edit}
            onRefresh={this.refresh}
        />;
    }

      

Any help would be appreciated.

+3


source to share


2 answers


you cannot set the state in the component WillMount because your component might be in a transient state. will also not trigger re-render . Either use componentWillReceiveProps or componentDidUpdate.

Now, aside from your problem, you are calling setState in a callback from an API request. and the problem is that you probably disabled that component and don't want to setStateState anymore.

you can fix it with a simple flag



constructor() {
    super();
    this.state = {
        users: [], request: {}
    };
    this.isMounted = false;
}
componentDidMount(){
    this.isMounted = true
}
componentWillUnmount(){
    this.isMounted = false;
}

      

then in your api request you will do this.

Api.UserList.get(this.state.request).then((response) => {
    console.log('ajax-data');
    if (response.isOk && this.isMounted) {
        this.setState({ users: response.data, request: response.state });
    }
});

      

+1


source


I think it's better to use componentWillMount()

instead componentDidMount()

, because you want to load the list and then set the state, not after the component has been installed.



-1


source







All Articles