react-next-keep-alive
v1.0.16
Published
Module for caching views in next.js
Downloads
1,170
Maintainers
Readme
react-next-keep-alive
Module for caching views in next.js (with restoring scroll position). It works almost like react-keep-alive and react-activation. Does not use external dependencies.
This component is build on next.js router, so it can be used with next.js only. Like other similar modules, it also keeps cached view in separate hidden div. Basic logic was taken from this answer to github issue (Thanks to @GusRuss89) and more logic was added to it (usage of HOC instead of routes, etc...).
The reason for creating this was that:
- react-keep-alive - Crashed my app because of different dom manipulations (like trying to remove or replace dom elements which are not present). Adding additional checks didn't solve the problem.
- react-activation - Client side dom structure did not match server side dom structure. In addition, it stopped working from react 17.
If you are not using next.js, there are some modules around that use react-router, so you can try those instead.
Install
npm install --save react-next-keep-alive
Usage
In your next.js project:
pages/_app.tsx (create one, if not present):
Wrap your <Component />
with <KeepAliveProvider />
import { AppProps } from 'next/app';
import { KeepAliveProvider } from 'react-next-keep-alive';
function MyApp ({ Component, pageProps }: AppProps) {
const router = useRouter();
return (
<KeepAliveProvider router={router}>
<Component {...pageProps} />
</KeepAliveProvider>
);
}
export default MyApp;
pages/*.tsx:
For any component that you want to cache, wrap its export with withKeepAlive
HOC and add unique name to it
import React, { useState } from 'react';
import Link from 'next/link';
import { withKeepAlive } from 'react-next-keep-alive';
const IndexPage = () => (
<>
My index page
</>
);
export default withKeepAlive(IndexPage, 'my-unique-name');
That's it!
withKeepAlive options
There are some additional options available for withKeepAlive
HOC:
withKeepAlive(Component, name: string | (({props, router}) => string), opts: Object)
name
Name is a string or function that returns a string.
props
and nextjs router
is passed to that function to help apply some more specific name, which might be needed for having multiple caches for the same component.
opts
| Key | type | default | Description | | :--- | :--- | :--- | :--- | | keepScrollEnabled | boolean | true | Setting this to false will disable scroll restoration. By default it is true and scroll position is restored. | | applyNewProps | boolean or (cachedProps, newProps) => Object | false | Default value of false mounts cached view with cached props. Setting this to true will apply new props to cached view. You can use a function here to decide which props to mount the component with - it gets cached props and new props as arguments and outputs combined props. |
Helpers
props
There are some props passed to component that is cached with withKeepAlive
HOC.
| prop | type | Description |
| :--- | :--- | :--- |
| isHiddenByKeepAlive | boolean | Is true
if component is currently cached and hidden in dom tree. Is false
if component is currently active |
| useEffect | Function | Works as original useEffect but only when component is visible. You should use that instead of original useEffect unless you know what you are doing.
import React, { useState } from 'react';
import { withKeepAlive } from 'react-next-keep-alive';
const Example = (props) => {
const {
isHiddenByKeepAlive, // This is true if component is currently hidden,
useEffect
} = props;
useEffect(() => {
// Runs only when cached component visible
return () => {
// Cleanup
}
}, [dep1, dep2, ...])
return (
<>
My index page
</>
);
};
export default withKeepAlive(Example, 'my-unique-name');
keepAliveLoadFromCache(name: string, enabled: boolean)
If you want to disable loading component from cache, use this method. Pass unique name that you gave to the component and boolean value of enabled/disabled.
import React, { useState } from 'react';
import Link from 'next/link';
import { withKeepAlive, keepAliveLoadFromCache } from 'react-next-keep-alive';
const IndexPage = () => {
// Disable loading from cache
keepAliveLoadFromCache('my-index-page', false);
return (
<>
My index page
</>
);
};
export default withKeepAlive(IndexPage, 'my-index-page');
keepAliveDropCache(name?: string | ((cacheKeys: string[]) => string | string[]), scrollToTop: boolean)
You can remove component(s) from cache and scroll window to top with this function.
- To remove all components from cache, do not pass any name.
- To remove single component from cache, pass in components name
- To remove multiple components, pass in a function which takes in array of cache keys and returns a single key or array of keys that will be removed.
You can import it like this: import { keepAliveDropCache } from 'react-next-keep-alive'
useKeepAliveMountEffect(name: string, effect: Function)
If you need to know, when cache component is mounted, you can use this hook.
You need to pass components unique name and effect function in order to use it.
This hook is accessible in any component, so you can use it for example in nested child component.
import { useKeepAliveMountEffect } from 'react-next-keep-alive'
useKeepAliveMountEffect('my-index-page', () => {
// Your code
});
useKeepAliveUnmountEffect(name: string, effect: Function)
If you need to know, when cache component is unmounted, you can use this hook.
You need to pass components unique name and effect function in order to use it.
This hook is accessible in any component, so you can use it for example in nested child component.
import { useKeepAliveUnmountEffect } from 'react-next-keep-alive'
useKeepAliveUnmountEffect('my-index-page', () => {
// Your code
});
Changelog
- Version 1.0.5 - Has a breaking change for
withKeepAlive
HOC. It now takes object as third argument instead of boolean. See more above. - Version 1.0.6 - Add keepAliveDropCache.
- Version 1.0.7 - Add identifiers to container and hidden components inside it.
- Version 1.0.8 - Change order - put keep-alive container as last in dom tree, so non-cached elements will be selected first when using querySelectors.
- Version 1.0.8 - Add component type in
withKeepAlive
HOC first argument, passisHiddenByKeepAlive
property to component so user knows if this component is currently cached and hidden if needed. - Version 1.0.9 - Add
isHiddenByKeepAlive
prop to cached component. - Version 1.0.11 - Update component type.
- Version 1.0.12 -
keepAliveDropCache
is now able to remove multiple caches. - Version 1.0.14 -
useEffect
is now passed to component which useswithKeepAlive
, which runs only when current component is visible. You should prefer using that instead of original useEffect.
License
MIT © https://github.com/AlexSapoznikov/react-next-keep-alive