score:70
without seeing the render function is a bit tough. although can already spot something you should do, every time you use an interval you got to clear it on unmount. so:
componentdidmount() {
this.loadinterval = setinterval(this.loadsearches, this.props.pollinterval);
}
componentwillunmount () {
this.loadinterval && clearinterval(this.loadinterval);
this.loadinterval = false;
}
since those success and error callbacks might still get called after unmount, you can use the interval variable to check if it's mounted.
this.loadinterval && this.setstate({
loading: false
});
hope this helps, provide the render function if this doesn't do the job.
cheers
score:0
just for reference. using cpromise with decorators you can do the following tricks: (live demo here)
export class testcomponent extends react.component {
state = {};
@canceled(function (err) {
console.warn(`canceled: ${err}`);
if (err.code !== e_reason_disposed) {
this.setstate({ text: err + "" });
}
})
@listen
@async
*componentdidmount() {
console.log("mounted");
const json = yield this.fetchjson(
"https://run.mocky.io/v3/7b038025-fc5f-4564-90eb-4373f0721822?mocky-delay=2s"
);
this.setstate({ text: json.stringify(json) });
}
@timeout(5000)
@async
*fetchjson(url) {
const response = yield cpfetch(url); // cancellable request
return yield response.json();
}
render() {
return (
<div>
asynccomponent: <span>{this.state.text || "fetching..."}</span>
</div>
);
}
@cancel(e_reason_disposed)
componentwillunmount() {
console.log("unmounted");
}
}
score:1
for posterity,
this error, in our case, was related to reflux, callbacks, redirects and setstate. we sent a setstate to an ondone callback, but we also sent a redirect to the onsuccess callback. in the case of success, our onsuccess callback executes before the ondone. this causes a redirect before the attempted setstate. thus the error, setstate on an unmounted component.
reflux store action:
generateworkflow: function(
workflowtemplate,
trackingnumber,
done,
onsuccess,
onfail)
{...
call before fix:
actions.generateworkflow(
values.workflowtemplate,
values.number,
this.setloading.bind(this, false),
this.successredirect
);
call after fix:
actions.generateworkflow(
values.workflowtemplate,
values.number,
null,
this.successredirect,
this.setloading.bind(this, false)
);
more
in some cases, since react's ismounted is "deprecated/anti-pattern", we've adopted the use of a _mounted variable and monitoring it ourselves.
score:3
class myclass extends component {
_ismounted = false;
constructor(props) {
super(props);
this.state = {
data: [],
};
}
componentdidmount() {
this._ismounted = true;
this._getdata();
}
componentwillunmount() {
this._ismounted = false;
}
_getdata() {
axios.get('https://example.com')
.then(data => {
if (this._ismounted) {
this.setstate({ data })
}
});
}
render() {
...
}
}
score:3
share a solution enabled by react hooks.
react.useeffect(() => {
let issubscribed = true
callapi(...)
.catch(err => issubscribed ? this.setstate(...) : promise.reject({ issubscribed, ...err }))
.then(res => issubscribed ? this.setstate(...) : promise.reject({ issubscribed }))
.catch(({ issubscribed, ...err }) => console.error('request cancelled:', !issubscribed))
return () => (issubscribed = false)
}, [])
the same solution can be extended to whenever you want to cancel previous requests on fetch id changes, otherwise there would be race conditions among multiple in-flight requests (this.setstate
called out of order).
react.useeffect(() => {
let iscancelled = false
callapi(id).then(...).catch(...) // similar to above
return () => (iscancelled = true)
}, [id])
this works thanks to closures in javascript.
in general, the idea above was close to the makecancelable approach recommended by the react doc, which clearly states
ismounted is an antipattern
credit
score:6
to whom needs another option, the ref attribute's callback method can be a workaround. the parameter of handleref is the reference to div dom element.
for detailed information about refs and dom: https://facebook.github.io/react/docs/refs-and-the-dom.html
handleref = (divelement) => {
if(divelement){
//set state here
}
}
render(){
return (
<div ref={this.handleref}>
</div>
)
}
score:13
the question is why am i getting this error when the component should already be mounted (as its being called from componentdidmount) i thought it was safe to set state once the component is mounted ?
it is not called from componentdidmount
. your componentdidmount
spawns a callback function that will be executed in the stack of the timer handler, not in the stack of componentdidmount
. apparently, by the time your callback (this.loadsearches
) gets executed the component has unmounted.
so the accepted answer will protect you. if you are using some other asynchronous api that doesn't allow you to cancel asynchronous functions (already submitted to some handler) you could do the following:
if (this.ismounted())
this.setstate(...
this will get rid of the error message you report in all cases though it does feel like sweeping stuff under the rug, particularly if your api provides a cancel capability (as setinterval
does with clearinterval
).
Source: stackoverflow.com
Related Query
- React warning about setState in unmounted component
- React Warning: Can't call setState (or forceUpdate) on an unmounted component
- react hook cant perform setstate in an unmounted component
- Can't perform a React state update on an unmounted component
- React useEffect causing: Can't perform a React state update on an unmounted component
- React - setState() on unmounted component
- React-hooks. Can't perform a React state update on an unmounted component
- Cleanup memory leaks on an Unmounted Component in React Hooks
- Can't call setState (or forceUpdate) on an unmounted component
- React setState can only update a mounted or mounting component
- Checking if a component is unmounted using react hooks?
- Warning: Can't perform a React state update on an unmounted component. In a functional component
- React 16: Error: Unable to find node on an unmounted component
- Warning: Can't call setState (or forceUpdate) on an unmounted component
- React Native Test Error - Unable to find node on an unmounted component
- Passing setState to child component using React hooks
- Warning about calling setState on an unmounted component
- React useCallback memory leak unmounted component
- useEffect - Can't perform a React state update on an unmounted component
- React Arrow Function Component - setState is not defined
- componentDidMount: Can't call setState (or forceUpdate) on an unmounted component
- ReactDOM.render: Unable to find node on an unmounted component after React upgrade from 16.4.2 to 16.5.2
- React Checkbox Stays Checked Even After Component is Unmounted
- Can't call setState (or forceUpdate) on an unmounted component. React
- Error : Can't perform a React state update on an unmounted component
- React JS: Component not updating, after calling setState
- Calling setState on an unmounted component
- React setState callback not called for external (npm packaged) component
- React - setState not re-rendering page when Axios call in separate component
- React JS - can't call setState on a component that is not yet mounted
More Query from same tag
- ReactJS getting results from a Promise
- How to fix Error: _registerComponent(...): Target container is not a DOM element. error?
- How to declare a state variable of type Set()?
- Is it possible to set the Analytics ID in gatsby-node.js?
- React setState inside function doesn't get read the first time
- React JS Reducer - Not able to do anything with the returned payload, only able to print
- state is not incrementing correctly reactjs
- How to get a users email app to pop up and allow them to send an email through their own app instead of through the website that they're visirting
- Want hide all row select option but not multiple row select options from MUIDatatables.Is it possible?
- React - Ways to update state after ajax post request
- Modal onClick glitch
- Open popup on DataTable row click in ReactJS
- React if statement in map inside JSX tag
- Input validation in react with functional component and useEffect hook
- Material UI Table not Updating when new records added
- react - not able to update state in input value
- Javascript conditions for state form option
- How to pass const to multiple components / Spliting React-Redux-Router files
- Stale closure when storing callback in parent component state
- Check if File or Module Has Been Imported
- How to stop TypeScript error 'Type A has no properties in common with Type B' when Type B "extends" Type A in some way
- creating initial state in context that depends on URL, window is not defined in NextJS
- React-hook-form with Material-ui textfield without autoFocus defaultValue disappeared during form submit
- Taking JSON values in a response and mapping them to a state object with keys?
- Setting up a working URL with React Router
- How to use Link tag
- Getting html tag into data from API post method
- How to make nodejs and react use different ports
- How to set variable from parent inside child's componentDidMount react?
- convert mySQL BLOB to HTML file in NodeJS/Reactjs