From a1a2e1d95fa97d0215d462c6da13b5be4e8a76d0 Mon Sep 17 00:00:00 2001 From: Shen Junru Date: Wed, 8 Jun 2022 11:14:39 +0800 Subject: [PATCH] feat: add useIgnoreKeepAlive() api --- src/index.tsx | 50 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 4276480..e66f610 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,6 +1,7 @@ import type { Fiber } from 'react-reconciler'; import React, { createContext, + useCallback, useContext, useEffect, useLayoutEffect, @@ -35,31 +36,38 @@ const enum Step { Effect = 0b0010, } +const randomKey = Math.random().toString(36).slice(2); +const CachesPropKey: unique symbol = ('__keepAliveCaches$' + randomKey) as any; +const MapperPropKey: unique symbol = ('__keepAliveMapper$' + randomKey) as any; + type KeepAliveCache = [Fiber, { current: boolean }]; type KeepAliveState = [Step, null | KeepAliveCache]; + type KeepAliveProps = { name: string; ignore?: boolean; children: React.ReactNode; }; -const randomKey = Math.random().toString(36).slice(2); -const CachesPropKey = '__keepAliveCaches$' + randomKey; -const MapperPropKey = '__keepAliveMapper$' + randomKey; +type RootContainer = null | (HTMLElement & { + [CachesPropKey]?: Map, + [MapperPropKey]?: Map, +}); + const KeepAliveContext = createContext(null); const KeepAliveProvider: React.FC<{ children: React.ReactNode; value: null | HTMLElement; }> = (props) => { - const value = props.value; + const context: RootContainer = props.value as any; useEffect(() => () => { - if (value) { - delete (value as any)[CachesPropKey]; - delete (value as any)[MapperPropKey]; + if (context) { + delete context[CachesPropKey]; + delete context[MapperPropKey]; } - }, [value]); + }, [context]); return ( @@ -124,19 +132,19 @@ const KeepAliveFinish: React.FC<{ }; const KeepAliveManage: React.FC = (props) => { - const context = useContext(KeepAliveContext); + const context: RootContainer = useContext(KeepAliveContext) as any; const cursor = useRef(null); const caches = useMemo((): Map => { - const value = (context as any)?.[CachesPropKey] || new Map(); + const value = context?.[CachesPropKey] || new Map(); if (context) { - (context as any)[CachesPropKey] = value; + context[CachesPropKey] = value; } return value; }, []); const mapper = useMemo((): Map => { - const value = (context as any)?.[MapperPropKey] || new Map(); + const value = context?.[MapperPropKey] || new Map(); if (context) { - (context as any)[MapperPropKey] = value; + context[MapperPropKey] = value; } return value; }, []); @@ -257,6 +265,22 @@ export function keepAlive

( }; } +export const useIgnoreKeepAlive = () => { + const context: RootContainer = useContext(KeepAliveContext) as any; + + return useCallback((name: string) => { + const caches = context?.[CachesPropKey]; + const mapper = context?.[MapperPropKey]; + const readKey = mapper?.get(name); + readKey && caches?.delete(readKey); + readKey && mapper?.forEach((value, key) => { + if (value === readKey) { + mapper.delete(key); + } + }); + }, [context]); +}; + export { markClassComponentHasSideEffectRender, markEffectHookIsOnetime,