反应页面记忆

时间:2021-03-19 08:26:31

标签: javascript reactjs next.js memoization

最近我遇到了在next.js的不同页面上记住多个状态的问题。页面上的 JSX 组件可能完全不同,因此很难想出一个通用的模式。当然,您可以使用 Context API 并在切换到另一个路由时保存公共页面状态,但在我的情况下,这将需要昂贵的重构。当拍摄页面状态快照时,我想出了一个解决方案。我想问社区这个解决方案生产准备了多少? live example 中有一个指向 ? repository 的链接。 您可以更改页面中的初始状态,然后确保返回页面时保留它们。

所有魔法都从这里开始:

可以缓存的路由列表(SSR 页面)。 不需要缓存所有的页面,但是你需要刻意去做 要缓存特定页面,您只需要在此处添加所需的路由

const ROUTES_CAN_BE_CACHED: Array<string> = ['/Page1', '/Page2', '/Page3'];

const router = useRouter();
const retainedComponents = useRef<Array<{ key: string; component: JSX.Element }> | undefined>(undefined);
const isRouteCouldBeCached = ROUTES_CAN_BE_CACHED.includes(router.asPath);

页面缓存功能

检查页面是否需要缓存 为此,当更改路由时,它会检查缓存的可能性

if (isRouteCouldBeCached) {
     // Checking whether a page with such a route has been previously cached
     const isPageAlreadyCached: boolean = Array.isArray(retainedComponents.current)
         ? retainedComponents.current.some((i) => i.key === router.asPath)
         : false;
     // If there is no such page in the cache, then add it
     if (!isPageAlreadyCached) {
         // Memoized component
         const MemoComponent = memo(Component);
         const newCachedObject = {
             key: router.asPath,
             component: (
                 <UniversalLayout>
                     <MemoComponent {...pageProps}/>
                 </UniversalLayout>
             ),
         };
         // Either we create a new array with cached pages, or add to the existing one
         switch (retainedComponents.current) {
             case undefined:
                 retainedComponents.current = new Array(newCachedObject);
                 break;
             default:
                 retainedComponents.current.push(newCachedObject);
                 break;
         }
     }
 }

渲染 JSX


    return (
       ...
                {retainedComponents.current?.map((item) => (
                    <div
                        key={item.key}
                        style={{
                            display: router.asPath === item.key ? 'block' : 'none',
                        }}
                    >
                        {item.component}
                    </div>
                ))}

                {!isRouteCouldBeCached && (
                    <UniversalLayout>
                        {showStartupHint ?
                            <StartupHint handleChangeStartupHint={handleChangeStartupHint}/> :
                            <Component
                                {...pageProps}

                            />
                        }
                    </UniversalLayout>
                )}
     ...
    ) ;
}

0 个答案:

没有答案
相关问题