Why does the state reset in react component when changing between pages using react-router?
As I understand it, you should be able to switch between routes (components) using react-router as long as you use the 'react' way of changing, ie. <Link to="/otherRoute" />. This is not the case for me and I do not see why. Here is the code:
App.js
import RoutesComp from "./RoutesComp";
import { Link } from "react-router-dom";
function App() {
return (
<div className="App">
<p>
<Link to="/state">State</Link>
</p>
<p>
<Link to="/dummy">dummy</Link>
</p>
<RoutesComp />
</div>
);
}
export default App;
StateComp.js
import React, { useState } from "react";
const StateComp = () => {
const [counter, setCounter] = useState(0);
return (
<>
<button onClick={() => setCounter((prev) => prev + 1)}>click to increment</button>
<p>{counter}</p>{" "}
</>
);
};
export default StateComp
RoutesComp.js
import React from "react";
import { Route, Switch } from "react-router-dom";
import StateComp from "./StateComp";
import Dummy from "./Dummy";
const RoutesComp = (props) => {
return (
<>
<Switch>
<Route path="/state" render={() => <StateComp />} />
<Route path="/dummy" render={() => <Dummy />} />
// I also tried it the original way
{/* <Route path="/state">
<StateComp />
</Route>
<Route path="/dummy">
<Dummy />
</Route> */}
</Switch>
</>
);
};
export default RoutesComp;
This produces the following:

When you click on the increment button, the count goes up, but when you go to the 'dummy' page and come back to the 'state' page, the counter is at 0 again.
From my research, react router difference between component and render it looks like the state will be reset if you create routes using
<Route path="/state">
<StateComp />
</Route>
<Route path="/dummy">
<Dummy />
</Route>
However, it seems like the way to get the state to not be reset is to use render={() => <Comp/>}.
I tried that as well and that did not work.
Can anyone offer some insight as to what I'm doing wrong?
EDIT: Dependencies/Versions
"dependencies": {
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router": "^5.0.0",
"react-router-dom": "^5.0.0",
"react-scripts": "4.0.3",
"web-vitals": "^1.1.2"
The Switch component only ever renders a single route, the earliest match wins. All the components whose routes do not get matched are unmounted.
To avoid this, you need to move you Route components outside of the Switch component and use the children property to render your component.
Here's an example that implements the above mentioned approach: example codesandbox link
Some other workarounds include:
redux or useContext APIHelpful links:
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