I have a component at a given route, say app.com/cars/1
I have a sidebar with links to different cars, eg /cars/2
, /cars/3
etc.
The issue I'm having is when you change links, say go from cars/1
to cars/2
, the component doesn't unmount, and I get componentWillReceiveProps
fired. If I go to another page with a different component, say /trucks
, the component is unmounted and all is well.
How can I unmount my component when the route changes? I have all kinds of state and flux stuff that I want cleared for this next car. Or if not unmount, is there a typical way people handle this kind of issue? I can't imagine this isn't very common.
(note I'm using react-router)
Unmount a React Node React has a top-level API called unmountComponentAtNode() that removes a component from a specific container. The function unmountComponentAtNode() takes an argument as a container from which the specific component should be removed.
Calling history. push() inside of a component seems to cause the entire react component to unmount and remount; causing pointless remote service calls.
Unmounting. This method is called when a component is being removed from the DOM: componentWillUnmount()
Since new release, it's possible to pass props directly via the Route component, without using a Wrapper.
I think the normal way to handle this is just to unregister and reregister your listeners, reset your state, and so on in componentWillReceiveProps
. It's normal to create abstractions around this behavior:
componentWillMount: function() {
this.setupStuff(this.props);
}
componentWillUnmount: function() {
this.tearDownStuff();
}
componentWillReceiveProps: function(nextProps) {
this.tearDownStuff();
this.setupStuff(nextProps);
}
setupStuff: function(props) {
this.setState(this.getDataFromStore(props.store));
props.store.listen(this.handler); // or whatever
}
tearDownStuff: function(props) {
props.store.unlisten(this.handler); // or whatever
}
However, if you really wanted to remount your components, there are a couple options you can use.
If you don't want any of your components to remain mounted across route changes, you can utilize the createElement
option of the router to add a unique key to the components:
function createElement(Component, props) {
var key = ...; // some key that changes across route changes
return <Component key={key} {...props} />;
}
// ...
<Router createElement={createElement}>
...
However, I don't recommend this. Not only does it make your app slower because every route component is remounting each time, but it also completely disables things like animations between subsequent renders of the same route handler with different props.
If you only want a certain route to always rerender, you can give it a key in the parent via React.cloneElement
:
render: function() {
var key = ...; // some key that changes across route changes
return React.cloneElement(
React.Children.only(this.props.children),
{key: key}
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With