如何缓存 React 延迟加载组件并防止不必要的卸载和重新挂载

问题描述 投票:0回答:1

我创建了一个可移动组件,

const componentsMap = new Map();
const useCachedLazy = (importFunc, namedExport) => {
if (!componentsMap.has(importFunc)) {
    const LazyComponent = lazy(() =>
      importFunc().then(module => ({
        default: namedExport ? module[namedExport] : module.default,
      }))
    );
    componentsMap.set(importFunc, LazyComponent);
  }

  return componentsMap.get(importFunc);
};

const loadable = (importFunc, { namedExport = null } = {}) => {
  const MemoizedLazyComponent = React.memo(props => {
    const LazyComponent = useCachedLazy(importFunc, namedExport);
    return (
        <LazyComponent {...props} />
    );
  });

  return MemoizedLazyComponent;
};


export default loadable;

您可以看到我尝试使用 memo 和 useCachedLazy 在这里缓存惰性组件。

我的路线在 App.js 中这样调用:

<Suspense fallback={<div><Spin /></div>}>
                  <Switch>
                    {routes.map(route => {
                      const LazyComponent = loadable(
                        () => Promise.resolve({ default: route.component }),
                        { namedExport: route.namedExport } // passing named exports to loadable
                      );

                      return route.auth ? (
                        <PrivateRoute
                          {...route}
                          key={route.key}
                          collapsed={collapsed}
                          toggleCollapsed={toggleCollapsed}
                          showHiddenTriggerKeyPress={showHiddenTriggerKeyPress}
                          component={LazyComponent} 
                          locale={locale}
                        />
                      ) : (
                        <Route {...route} key={route.key} component={LazyComponent} />
                      );
                    })}
                  </Switch>
                </Suspense>

在routes数组中,我直接在proproute.component中传递组件。

现在延迟加载对我来说确实提高了加载速度,所以这是一件好事。但每当发生变化时,所有组件都会重新安装,而不是应该重新渲染。请提及任何可能的解决方案。

reactjs react-hooks lazy-loading react-suspense
1个回答
0
投票

有多项修复;

  1. 使用稳定的参考
    LazyComponent

    避免为每个渲染创建新的
    LazyComponent
    。相反,以在渲染之间持续存在的方式缓存
    LazyComponent
    实例,类似于您对
    useCachedLazy
    所做的操作。
const cachedComponentsMap = new Map();

const loadable = (importFunc, { namedExport = null } = {}) => {
  const cachedKey = `${importFunc}-${namedExport}`;

  if (!cachedComponentsMap.has(cachedKey)) {
    const MemoizedLazyComponent = React.memo(props => {
      const LazyComponent = useCachedLazy(importFunc, namedExport);
      return <LazyComponent {...props} />;
    });

    cachedComponentsMap.set(cachedKey, MemoizedLazyComponent);
  }

  return cachedComponentsMap.get(cachedKey);
};
  1. 路由中的稳定密钥
    确保每个路由的密钥稳定并与路由本身相关联。如果

    key
    动态变化,React 将卸载并重新挂载组件。

  2. 在路由级组件上使用

    React.memo

    考虑包装
    PrivateRoute
    或使用
    React.memo
    路由组件,以防止由于 prop 更改而导致不必要的重新渲染或重新安装。

© www.soinside.com 2019 - 2024. All rights reserved.