Learning about React Router I noticed that a component will go back to its initial state when switching from route a to b.
Why the same doesn't happen when clicking over again on the same route i.e a to a?
How could I implement a way where clicking on the same route <NavLink/>
the component reverts to its original state - Should/Could that be done on the onChange
hook of React Router?
If this is an anti-pattern please enlighten me on how else I could accomplish the following: I need my component to revert to its original state not only when switching routes but also in the case that a user chooses to click on the same route again.
Below, an abstraction of the issue:
Clicking on the Cat <p/>
tag should change its color to green
, clicking on the same route <NavLink to="/cat-view">cat</NavLink>
should revert the cat color state back to its initial state. i.e color: false
Just like it does when switching from route a to b (in my case cat to dog)
// Cat Component
import React, { useState } from "react";
export const Cat = () => {
const [color, setColor] = useState(false);
function ChangeColor() {
setColor(true);
}
console.log(color)
return (
<p onClick={ChangeColor}>
Click on this <span className={color ? "green" : " "}>Cat</span>
</p>
);
};
import {
BrowserRouter as Router,
Route,
NavLink,
Switch,
withRouter,
browserHistory
} from "react-router-dom";
// Main Component
class PetShop extends Component {
state = {};
render() {
return (
<Router history={browserHistory}>
<div>
<ul>
<li>
<NavLink to="/">home</NavLink>
</li>
<li>
<NavLink to="/cat-view">cat</NavLink>
</li>
<li>
<NavLink to="/dog-view">dog</NavLink>
</li>
</ul>
<Switch>
<Route
path="/cat-view"
render={() => <Cat/>}
onChange={console.log("cat route changed")}
/>
<Route
path="/dog-view"
render={() => <Dog/>}
onChange={console.log("dog route changed")}
/>
</Switch>
</div>
</Router>
);
}
}
export default withRouter(PetShop);
here's a code sandbox
Since you are using the react-router Switch
component which only renders the first match, when you switch from Route a to b, a is being unmounted; this tosses out all of its state so if you switch back to a you have a brand new component that gets the initial value you have specified for its state (e.g. false
for Cat
color
). Clicking on a NavLink
that doesn't change the rendered Route
leaves the same element in place and has no effect on its state.
If you want to change the state when you click on its NavLink
, then you need to explicitly do that.
There are two main ways you could do this:
Here's a modified version of your sandbox that demonstrates all of these:
Cat
demonstrates the first approach.
I've moved the state from Cat
up to PetShop
(Cat now just uses props). I also added an onClick
to the NavLink
for cat that sets the state back to false
.
Dog
demonstrates the second approach.
This approach would work better in a more complicated scenario where the component has lots of its own state and you want it all to reset if you click on the link again.
Bunny
demonstrates the third approach.
This is similar to the key property for the Dog example, but doesn't cause a remount. Bunny
just uses the resetIndex
in an effect to cause Bunny
to reset itself. There are probably several technical approaches for this. You just want a way to signal the child to reset itself.
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