react-router-cache-route
Route with cache for react-router V5 like <keep-alive /> in Vue
Top Related Projects
Declarative routing for React
🧭 Declarative, asynchronous routing for React.
🥢 A minimalist-friendly ~2.1KB routing for React and Preact
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering.
Quick Overview
CJY0208/react-router-cache-route is a React library that extends react-router to provide route caching functionality. It allows developers to cache route components, preserving their state and improving performance by reducing unnecessary re-renders when navigating between routes.
Pros
- Improves application performance by caching route components
- Preserves component state when navigating between routes
- Seamlessly integrates with existing react-router setups
- Provides flexible configuration options for cache behavior
Cons
- May increase memory usage due to caching of components
- Requires careful consideration of which routes to cache to avoid potential issues
- Limited documentation and examples available
- Not actively maintained (last update was over 2 years ago)
Code Examples
- Basic usage of CacheRoute:
import { CacheRoute, CacheSwitch } from 'react-router-cache-route'
function App() {
return (
<Router>
<CacheSwitch>
<CacheRoute path="/home" component={Home} />
<CacheRoute path="/about" component={About} />
<Route path="/contact" component={Contact} />
</CacheSwitch>
</Router>
)
}
- Using CacheRoute with custom caching behavior:
<CacheRoute
path="/dashboard"
component={Dashboard}
cacheKey="dashboard"
when="always"
/>
- Implementing a drop cache button:
import { dropByCacheKey } from 'react-router-cache-route'
function DropCacheButton() {
return (
<button onClick={() => dropByCacheKey('dashboard')}>
Clear Dashboard Cache
</button>
)
}
Getting Started
-
Install the package:
npm install react-router-cache-route
-
Import and use CacheRoute and CacheSwitch in your React application:
import { CacheRoute, CacheSwitch } from 'react-router-cache-route' import { BrowserRouter as Router } from 'react-router-dom' function App() { return ( <Router> <CacheSwitch> <CacheRoute path="/home" component={Home} /> <CacheRoute path="/about" component={About} /> <Route path="/contact" component={Contact} /> </CacheSwitch> </Router> ) }
-
Customize caching behavior as needed using props like
cacheKey
andwhen
.
Competitor Comparisons
Declarative routing for React
Pros of react-router
- Widely adopted and maintained by a large community
- Comprehensive documentation and extensive ecosystem
- Seamless integration with React and other popular libraries
Cons of react-router
- Lacks built-in caching mechanism for route components
- More complex setup for advanced routing scenarios
- Steeper learning curve for beginners
Code Comparison
react-router-cache-route:
import { CacheRoute, CacheSwitch } from 'react-router-cache-route'
<CacheSwitch>
<CacheRoute path="/home" component={Home} />
<CacheRoute path="/about" component={About} />
</CacheSwitch>
react-router:
import { Route, Switch } from 'react-router-dom'
<Switch>
<Route path="/home" component={Home} />
<Route path="/about" component={About} />
</Switch>
Summary
react-router is a more established and feature-rich routing solution for React applications, offering extensive documentation and community support. However, it lacks built-in caching capabilities for route components, which react-router-cache-route provides out of the box. react-router-cache-route offers a simpler API for caching route components, but may have a smaller ecosystem and less frequent updates compared to react-router. The choice between the two depends on the specific needs of your project, particularly if route component caching is a priority.
Pros of reach/router
- More comprehensive routing solution with built-in accessibility features
- Simpler API and easier to use for beginners
- Better TypeScript support out of the box
Cons of reach/router
- Less flexible for complex routing scenarios
- Lacks built-in caching mechanism for route components
- Smaller community and fewer third-party extensions
Code Comparison
react-router-cache-route:
import { CacheRoute, CacheSwitch } from 'react-router-cache-route'
<CacheSwitch>
<CacheRoute path="/home" component={Home} />
<CacheRoute path="/about" component={About} />
</CacheSwitch>
reach/router:
import { Router } from '@reach/router'
<Router>
<Home path="home" />
<About path="about" />
</Router>
react-router-cache-route focuses on caching route components, while reach/router provides a more straightforward routing approach. The former offers more control over component caching, which can be beneficial for performance optimization in complex applications. reach/router, on the other hand, emphasizes simplicity and accessibility, making it a good choice for smaller projects or those prioritizing ease of use.
🧭 Declarative, asynchronous routing for React.
Pros of Navi
- Built-in code splitting and lazy loading support
- More comprehensive routing solution with built-in navigation components
- Better TypeScript support and type safety
Cons of Navi
- Steeper learning curve due to its unique approach to routing
- Less flexibility in terms of customization compared to react-router-cache-route
- Smaller community and ecosystem
Code Comparison
react-router-cache-route:
<CacheRoute
path="/user/:id"
component={UserProfile}
cacheKey={props => props.match.params.id}
/>
Navi:
<Route
getComponent={() => import('./UserProfile')}
getData={({ params }) => fetchUserData(params.id)}
/>
Both libraries aim to improve routing in React applications, but they take different approaches. react-router-cache-route focuses on caching route components, while Navi provides a more comprehensive routing solution with built-in navigation and data fetching capabilities. The choice between the two depends on the specific needs of your project and your preferred routing paradigm.
🥢 A minimalist-friendly ~2.1KB routing for React and Preact
Pros of wouter
- Lightweight and minimalistic, with a smaller bundle size
- Simple API that's easy to learn and use
- No external dependencies, reducing potential conflicts
Cons of wouter
- Less feature-rich compared to react-router-cache-route
- May require additional custom implementation for complex routing scenarios
- Lacks built-in caching functionality for route components
Code Comparison
wouter:
import { Route, Switch } from "wouter";
<Switch>
<Route path="/users/:id" component={UserProfile} />
<Route path="/about" component={About} />
</Switch>
react-router-cache-route:
import { CacheRoute, CacheSwitch } from 'react-router-cache-route';
<CacheSwitch>
<CacheRoute path="/users/:id" component={UserProfile} />
<CacheRoute path="/about" component={About} />
</CacheSwitch>
The main difference is that react-router-cache-route provides caching functionality out of the box, while wouter focuses on simplicity and lightweight routing. Choose wouter for simpler projects or when bundle size is a concern, and react-router-cache-route for applications that benefit from component caching and more advanced routing features.
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering.
Pros of TanStack Router
- Type-safe routing with automatic type inference
- Built-in support for nested layouts and data loading
- Framework-agnostic, can be used with React, Vue, or vanilla JavaScript
Cons of TanStack Router
- Steeper learning curve due to its unique approach to routing
- Less community support and fewer resources compared to more established routing libraries
Code Comparison
react-router-cache-route:
<CacheRoute path="/user/:id" component={UserProfile} />
TanStack Router:
const routeTree = routeTree({
user: {
$id: String,
component: UserProfile,
},
})
Key Differences
- react-router-cache-route focuses on caching route components, while TanStack Router provides a more comprehensive routing solution
- TanStack Router uses a declarative approach to define routes, whereas react-router-cache-route extends React Router's syntax
- TanStack Router offers more advanced features like type safety and built-in data loading, but may be overkill for simpler applications
Use Cases
- Choose react-router-cache-route for:
- Projects already using React Router
- Simple caching needs for route components
- Choose TanStack Router for:
- Type-safe routing in TypeScript projects
- Complex routing scenarios with nested layouts and data dependencies
- Framework-agnostic applications
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
CacheRoute
English | ä¸æ说æ
Route with cache for react-router
like keep-alive
in Vue.
If you want <KeepAlive />
only, try react-activation
React v15+
React-Router v4+
Problem Scenarios
Using Route
, component can not be cached while going forward or back which lead to losing data and interaction
Reason & Solution
Component would be unmounted when Route
was unmatched
After reading source code of Route
we found that using children
prop as a function could help to control rendering behavior.
Hiding instead of Removing would fix this issue.
https://github.com/remix-run/react-router/blob/v5.3.4/packages/react-router/modules/Route.js#L46-L61
Install
npm install react-router-cache-route --save
# or
yarn add react-router-cache-route
Usage
Replace Route
with CacheRoute
Replace Switch
with CacheSwitch
(Because Switch
only keeps the first matching state route and unmount the others)
import React from 'react'
import { HashRouter as Router, Route } from 'react-router-dom'
import CacheRoute, { CacheSwitch } from 'react-router-cache-route'
import List from './views/List'
import Item from './views/Item'
const App = () => (
<Router>
<CacheSwitch>
<CacheRoute exact path="/list" component={List} />
<Route exact path="/item/:id" component={Item} />
<Route render={() => <div>404 Not Found</div>} />
</CacheSwitch>
</Router>
)
export default App
CacheRoute props
name | type | default | description |
---|---|---|---|
when | String / Function | "forward" | Decide when to cache |
className | String | - | className prop for the wrapper component |
behavior | Function | cached => cached ? { style: { display: "none" }} : undefined | Return props effective on the wrapper component to control rendering behavior |
cacheKey | String / Function | - | For imperative control caching |
multiple (React v16.2+) | Boolean / Number | false | Allows different caches to be distinguished by dynamic routing parameters. When the value is a number, it indicates the maximum number of caches. When the maximum value is exceeded, the oldest updated cache will be cleared. |
unmount (UNSTABLE) | Boolean | false | Whether to unmount the real dom node after cached, to save performance (Will cause losing the scroll position after recovered, fixed with saveScrollPosition props) |
saveScrollPosition (UNSTABLE) | Boolean | false | Save scroll position |
CacheRoute
is only a wrapper component that works based on the children
property of Route
, and does not affect the functionality of Route
itself.
For the rest of the properties, please refer to https://reacttraining.com/react-router/
About when
The following values can be taken when the type is String
- [forward] Cache when forward behavior occurs, corresponding to the
PUSH
orREPLACE
action in react-router - [back] Cache when back behavior occurs, corresponding to the
POP
action in react-router - [always] Always cache routes when leave, no matter forward or backward
When the type is Function
, the component's props
will be accepted as the first argument, return true/false
to determine whether to cache.
CacheSwitch props
name | type | default | description |
---|---|---|---|
which | Function | element => element.type === CacheRoute | <CacheSwitch> only saves the first layer of nodes which type is CacheRoute by default, which prop is a function that would receive a instance of React Component, return true/false to decide if <CacheSwitch> need to save it, reference #55 |
Lifecycles
Hooks
use useDidCache
and useDidRecover
to inject customer Lifecycle didCache
and didRecover
import { useDidCache, useDidRecover } from 'react-router-cache-route'
export default function List() {
useDidCache(() => {
console.log('List cached 1')
})
// support multiple effect
useDidCache(() => {
console.log('List cached 2')
})
useDidRecover(() => {
console.log('List recovered')
})
return (
// ...
)
}
Class Component
Component with CacheRoute will accept one prop named cacheLifecycles
which contains two functions to inject customer Lifecycle didCache
and didRecover
import React, { Component } from 'react'
export default class List extends Component {
constructor(props) {
super(props)
props.cacheLifecycles.didCache(this.componentDidCache)
props.cacheLifecycles.didRecover(this.componentDidRecover)
}
componentDidCache = () => {
console.log('List cached')
}
componentDidRecover = () => {
console.log('List recovered')
}
render() {
return (
// ...
)
}
}
Drop cache
You can manually control the cache with cacheKey
prop and dropByCacheKey
function.
import CacheRoute, { dropByCacheKey, getCachingKeys } from 'react-router-cache-route'
...
<CacheRoute ... cacheKey="MyComponent" />
...
console.log(getCachingKeys()) // will receive ['MyComponent'] if CacheRoute is cached which `cacheKey` prop is 'MyComponent'
...
dropByCacheKey('MyComponent')
...
Clear cache
You can clear cache with clearCache
function.
import { clearCache } from 'react-router-cache-route'
clearCache()
Top Related Projects
Declarative routing for React
🧭 Declarative, asynchronous routing for React.
🥢 A minimalist-friendly ~2.1KB routing for React and Preact
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot