I have a situation where few routes consists of the same component and I want to preserve its state, but with this behavior it's fairly impossible.
Live example (look at seconds elapsed): https://csb-43lp1km647-nkiinaibit.now.sh
CodeSandbox: https://codesandbox.io/s/43lp1km647
Of course I could save and restore state of timer while changing routes, but my app has an infinite CSS transition as a background (not on every route).
I was trying adding keys, even portal, but it still remounts everything.
Is there any way to enforce typical React's reconciliation (remount only elements that have to be remounted)?
Update:
Just found out that <Switch />
will render everything until it finds element that matches, and that could be either a certain <Route />
or any element except it's inside <Fragment />
.
Code:
<Router history={history}>
<Switch>
<Route path="/third" component={RouteWithoutTimer} />
<React.Fragment>
<Timer />
<Route exact path="/" component={FirstRoute} />
<Route path="/second" component={SecondRoute} />
</React.Fragment>
</Switch>
</Router>
Or with wildcard route:
<Router history={history}>
<Switch>
<Route path="/third" component={RouteWithoutTimer} />
<React.Fragment>
<Timer />
<Switch>
<Route exact path="/" component={FirstRoute} />
<Route component={NotFoundRoute} />
</Switch>
</React.Fragment>
</Switch>
</Router>
It's not a solution I was looking for, but it works fine.
Using componentDidUpdate method of React page lifecycle, you can handled or disabled go back functionality in browser. basically componentDidUpdate method will call automatocally when component got updated. so once your component is updated you can prevent to go back as below.
To restrict access to routes in React Router, we set the render prop to a function that renders the component we want according to the condition we're checking. import { Route, Redirect } from "react-router"; <Route exact path="/" render={() => (loggedIn ?
for more information you can read the documentation. @vsync docs Instead of conditionally rendering a <Prompt> behind a guard, you can always render it but pass when={true} or when={false} to prevent or allow navigation accordingly. This is no longer the case with Router v6, unfortunately as Prompt was removed.
You are mounting a new instance of Timer
in each route.
If you want to share a component across routes, you should lift it to the parent component of the routes:
<React.Fragment>
<Timer />
<Switch>
<Route exact path="/" component={FirstRoute} />
<Route path="/second" component={SecondRoute} />
</Switch>
</React.Fragment>
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