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.
source to share
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 });
}
});
source to share