Closed Leecason closed 1 year ago
目前没有cache数量控制的功能。
只有 <KeepAlive ignore>
或者 useIgnoreKeepAlive()
用来消除 cache。
也可以自己实现计数功能。
欢迎提PR
如果我想基于已有的 API 来实现最大缓存数量是 5,可以怎么写呢
import * as React from 'react';
import { keepAlive, useIgnoreKeepAlive } from 'react-fiber-keep-alive';
const KeepAliveControllerContext = React.createContext<null | ((name: string) => void)>(null);
export const KeepAliveController: React.FC<{
max: number;
children?: React.ReactNode;
}> = ({ max, children }) => {
const size = React.useRef(max);
size.current = max;
const [fifo, setFIFO] = React.useState<string[]>([]);
const clear = useIgnoreKeepAlive();
const push = React.useCallback((name: string) => setFIFO((list) => {
const rest = list.filter((e) => e !== name);
return [...rest, name];
}), []);
React.useEffect(() => {
if (Number.isFinite(max) && 0 < max) {
fifo.slice(0, Math.max(0, fifo.length - max)).forEach(clear);
}
}, [max, fifo]);
return (
<KeepAliveControllerContext.Provider value={push}>
{children}
</KeepAliveControllerContext.Provider>
);
};
const YourComponent: React.FC = () => null;
keepAlive(YourComponent as React.FC, () => {
const name = 'unique-key';
// add this on the place you want control by the max cache size
const onSave = React.useContext(KeepAliveControllerContext) || undefined;
// onSave() prop since 0.7.0
return { name, onSave };
});
// const app = (
// <KeepAlive.Provider value={/* ... */}>
// <KeepAliveController max={10}>
// {/* ... */}
// </KeepAliveController>
// </KeepAlive.Provider>
// );
import * as React from 'react'; import { keepAlive, useIgnoreKeepAlive } from 'react-fiber-keep-alive'; const KeepAliveControllerContext = React.createContext<null | ((name: string) => void)>(null); export const KeepAliveController: React.FC<{ max: number; children?: React.ReactNode; }> = ({ max, children }) => { const size = React.useRef(max); size.current = max; const [fifo, setFIFO] = React.useState<string[]>([]); const clear = useIgnoreKeepAlive(); const push = React.useCallback((name: string) => setFIFO((list) => { const rest = list.filter((e) => e !== name); return [...rest, name]; }), []); React.useEffect(() => { if (Number.isFinite(max) && 0 < max) { fifo.slice(0, Math.max(0, fifo.length - max)).forEach(clear); } }, [max, fifo]); return ( <KeepAliveControllerContext.Provider value={push}> {children} </KeepAliveControllerContext.Provider> ); }; const YourComponent: React.FC = () => null; keepAlive(YourComponent as React.FC, () => { const name = 'unique-key'; // add this on the place you want control by the max cache size const onSave = React.useContext(KeepAliveControllerContext) || undefined; // onSave() prop since 0.7.0 return { name, onSave }; }); // const app = ( // <KeepAlive.Provider value={/* ... */}> // <KeepAliveController max={10}> // {/* ... */} // </KeepAliveController> // </KeepAlive.Provider> // );
感谢~还是希望提供方能原生支持,像 Vue 的 keep-alive 那样
每个项目对 cache 的管理会有不同的需求,所以不会加入原生支持。
0.7.0 中已经把 KeepAliveContext 给暴露出来了,不用上面的代码也可以做到全局实现。
可以用其他的 LRU 库对应实现 Map 的几个 API 就可以实现 cache 的 LRU 管理。
用 <KeepAlive.Context.Provider>
代替 <KeepAlive.Provider>
提供 context 即可。
对于TS,之后 0.7.1 中会把用到的 Map 类型抽象成 IMap 接口。
https://github.com/StructureBuilder/react-keep-alive/ 有 max 属性设置最大缓存数量,在超出最大值之后就会删除缓存中的值