A React Router
<Switch> which can leave inactive routes mounted-but-inactive until you navigate back.
Part of React Hibernate
By defaut, navigating from one
<Route> to another in react-router will unmount the old route's tree.
If you return to it, it will be remounted from scratch.
This library adds
<HibernatingRoute>: drop-in replacements for
which do not immediately unmount components when you navigate away. If you return, the prior tree will be restored,
local state and all.
;// then render:<HibernatingSwitch maxCacheTime=60000>/* Use the "Hibernating" variants exactly like the standard ones */<HibernatingRoute path="/foo" component=... /><HibernatingRoute path="/bar" render=... />/* You can mix and match: use them alongside the normal react-router components */<Route path="/baz" component=... /><Redirect from="/something-else" to="/foo" />/* If you have your own custom components, add an isHibernatingRoute prop */<MyPrivateRoute path="/secret" component=... isHibernatingRoute /></HibernatingSwitch>
Props for HibernatingSwitch
maxCacheSize (number, default: 5)
Number of subtrees to keep in the cache, including the current one.
path is used for the cache keys.
Set a falsy value to disable.
maxCacheTime (milliseconds, default: 5 minutes)
Time after which a subtree is removed from the cache. Set a falsy value to disable.
WrapperComponent (React component, default: none)
A component which wraps all potentially-hibernatable routes. It receives a
React-Pauseable-Containers was created for this.
How it Works
When you revisit a route which is still in the cache, its prior subtree is reattached. Because the elements and instances were not destroyed, all prior state is still present -- both React state and dom state.
Preventing Extra Work in Inactive Routes
Previously-rendered trees are still mounted when inactive: they're just not attached to the dom.
HibernatingRoute will suppress the normal render cycle for inactive subtrees, but if a component in the subtree
experiences a state change or context update then it will rerun.
This is fundamental to React and cannot be avoided.
In most cases this is fine -- inactive subtrees still use minimal resources -- but if the component render is slow or has side effects then you may want to avoid running it at all.
You can do that by setting a
WrapperComponent which halts context updates.
React-Pauseable-Containers was created for this: you can use its components directly,
compose them together to make your
WrapperComponent, or follow the examples to make your own from scratch.
- Proof of concept
- Project scaffolding
- Core functionality
- Initial release
useHibernatingEffecthook (successfully prototyped)
maxCacheTimeoverride per-route (successfully prototyped)
- Explore: Options to better control which/when to add a subtree
- Explore: React-Router v6
"Cannot update a component from inside the function body of a different component" warning in React 16.13+
- This will be addressed as part of supporting React-Router v6, when subtree activation will need to be done via a component instead of a callback.