React Activation
English | 中文说明
Implementation of the <keep-alive />
function in Vue
For React
More stable <KeepAlive />
function with babel
pre-compilation

More examples
Compatibility
-
React v17+ (beta)
-
React v16+
-
Preact v10+
-
Compatible with SSR
Install
yarn add react-activation# or npm install react-activation
Usage
react-activation/babel
plugins in .babelrc
1. Add
The plugin adds a _nk
attribute to each JSX element during compilation to help the react-activation
runtime generate an unique identifier by render location base on react-node-key
.
"plugins": "react-activation/babel"
<AliveScope>
outer layer at a location that will not be unmounted, usually at the application entrance
2. In your business code, place the Note: When used with react-router
or react-redux
, you need to place <AliveScope>
inside <Router>
or <Provider>
// entry.js ReactDOM
<KeepAlive>
3. Wrap the components that need to keep states with Like the <Counter>
component in the example
// Test.js { const count setCount = return <div> <p>count: count</p> <button onClick= >Add</button> </div> } { const show setShow = return <div> <button onClick= >Toggle</button> show && <KeepAlive> <Counter /> </KeepAlive> </div> }
Lifecycle
ClassComponent
works with withActivation
decorator
Use componentDidActivate
and componentWillUnactivate
to correspond to the two states of "activate" and "unactivate" respectively.
FunctionComponent
uses the useActivate
and useUnactivate
hooks respectively
... @withActivation ... { console } { console } ...... { ...}... { ... return show && <KeepAlive> <TestClass /> <TestFunction /> </KeepAlive> }...
true
by default)
Save Scroll Position (<KeepAlive />
would try to detect scrollable nodes in its children
, then, save their scroll position automaticlly before componentWillUnactivate
and restore saving position after componentDidActivate
If you don't want <KeepAlive />
to do this thing, set saveScrollPosition
prop to false
<KeepAlive saveScrollPosition=false />
If your components share screen scroll container, document.body
or document.documentElement
, set saveScrollPosition
prop to "screen"
can save sharing screen container's scroll position before componentWillUnactivate
<KeepAlive saveScrollPosition="screen" />
Multiple Cache
Under the same parent node, <KeepAlive>
in the same location will use the same cache by default.
For example, with the following parameter routing scenario, the /item
route will be rendered differently by id
, but only the same cache can be kept.
<Route path="/item/:id" render= <KeepAlive> <Item ...props /> </KeepAlive> />
Similar scenarios, you can use the id
attribute of <KeepAlive>
to implement multiple caches according to specific conditions.
<Route path="/item/:id" render= <KeepAlive id=propsmatchparamsid> <Item ...props /> </KeepAlive> />
Cache Control
Automatic control cache
Add the when
attribute to the <KeepAlive />
tag that needs to control the cache. The value is as follows
when
type is Boolean
When the - true: Cache after uninstallation
- false: Not cached after uninstallation
<KeepAlive when=false>
when
type is Array
When the The 1th parameter indicates whether it needs to be cached at the time of uninstallation.
The 2th parameter indicates whether to unload all cache contents of <KeepAlive>
, including all <KeepAlive>
nested in <KeepAlive>
.
// For example:// The following indicates that it is not cached when uninstalling// And uninstalls all nested `<KeepAlive>`<KeepAlive when=false true> ... <KeepAlive> ... <KeepAlive>...</KeepAlive> ... </KeepAlive> ...</KeepAlive>
when
type is Function
When the The return value is the above Boolean
or Array
, which takes effect as described above.
Manually control the cache
-
Add the
name
attribute to the<KeepAlive>
tag that needs to control the cache. -
Get control functions using
withAliveScope
oruseAliveController
-
drop(name)
Unload the
<KeepAlive>
node in cache state by name. The name can be of typeString
orRegExp
. Note that only the first layer of content that hits<KeepAlive>
is unloaded and will not be uninstalled in<KeepAlive>
. Would not unload nested<KeepAlive>
-
dropScope(name)
Unloads the
<KeepAlive>
node in cache state by name. The name optional type isString
orRegExp
, which will unload all content of<KeepAlive>
, including all<KeepAlive>
nested in<KeepAlive>
. -
clear()
will clear all
<KeepAlive>
in the cache -
getCachingNodes()
Get all the nodes in the cache
-
......<KeepAlive name="Test"> ... <KeepAlive> ... <KeepAlive> ... </KeepAlive> ... </KeepAlive> ...</KeepAlive>... { const drop dropScope clear getCachingNodes = return ... }// or@withAliveScope { const drop dropScope clear getCachingNodes = thisprops return ... }...
Principle
Pass the children
attribute of <KeepAlive />
to <AliveScope />
and render it with <Keeper />
After rendering <Keeper />
, the content is transferred to <KeepAlive />
through DOM
operation.
Since <Keeper />
will not be uninstalled, caching can be implemented.

Breaking Change
-
<KeepAlive />
needs to pass children to<AliveScope />
, so the rendering of the real content will be slower than the normal situationWill have a certain impact on the function of strictly relying on the lifecycle order, such as getting the value of
ref
incomponentDidMount
, as follows{console // will log <div /> instanceconsole // will log undefined}{return<div><divref= {thisoutside = ref}>Outside KeepAlive</div><KeepAlive><divref= {thisinside = ref}>Inside KeepAlive</div></KeepAlive></div>}The above error in
ClassComponent
can be fixed by using thewithActivation
high-level componentFunctionComponent
currently has no processing method, you can usesetTimeout
ornextTick
to delay ref getting behavior@withActivation{console // will log <div /> instanceconsole // will log <div /> instance}{return<div><divref= {thisoutside = ref}>Outside KeepAlive</div><KeepAlive><divref= {thisinside = ref}>Inside KeepAlive</div></KeepAlive></div>} -
Destructive impact on
Context
, need to be manually fixedProblem reference: https://github.com/StructureBuilder/react-keep-alive/issues/36
<Provider value=1>show &&<KeepAlive><Consumer>context // Since the rendering level is broken, the context cannot be obtained here.<Test contextValue=context /></Consumer></KeepAlive><button onClick=toggle>toggle</button></Provider>Choose a repair method
-
Create
Context
usingcreateContext
exported fromreact-activation
-
Fix the affected
Context
withfixContext
exported fromreact-activation
...const Provider Consumer =...// or...const Context =const Provider Consumer = Context... -
-
Affects the functionality that depends on the level of the React component, as follows
- Fix
withRouter/hooks
of react-router -
Error Boundaries(Fixed) -
React.Suspense & React.lazy(Fixed) - React Synthetic Event Bubbling Failure
- Other undiscovered features
- Fix