Reactjs 反应延迟加载的组件松开它';s状态(已卸载)

Reactjs 反应延迟加载的组件松开它';s状态(已卸载),reactjs,react-router,lazy-loading,react-hooks,Reactjs,React Router,Lazy Loading,React Hooks,我有以下组件,可在需要时(路线更改时)加载我的组件 功能动态阅读器(道具){ const LazyComponent=React.lazy(()=>import(`${props.component}'); 返回( ); } 我的路由(使用React路由器)如下所示: <Switch> {routes.map((prop, key) => { return ( <

我有以下组件,可在需要时(路线更改时)加载我的组件

功能动态阅读器(道具){
const LazyComponent=React.lazy(()=>import(`${props.component}');
返回(
);
}
我的路由(使用React路由器)如下所示:

            <Switch>
            {routes.map((prop, key) => {
              return (
                <Route
                  exact
                  path={prop.path}
                  render={() => (
                    <DynamicLoader component={prop.component} />
                  )}
                  key={key}
                />
              );
            })}
          </Switch>

{routes.map((道具,键)=>{
返回(
(
)}
key={key}
/>
);
})}
就为每个路由装载组件而言,这工作得很好,但是,对于父组件中的每个更改,React都是卸载和重新装载延迟加载的组件(而不是重新渲染)。这会导致所有内部状态重置,这当然是不希望的。有人能推荐一些解决方案吗?
下面是一个演示此问题的示例

每当呈现父对象时,
DynamicLoader
就会重新创建
LazyComponent
。React会看到一个新组件(不是同一个对象),卸载前一个组件,然后装载到新组件

要解决此问题,请使用inside
DynamicLoader
来记忆当前的
LazyComponent
,并且仅在
props.component
实际更改时才重新创建它:

const DynamicLoader = ({ component, parentUpdate }) => {
  const LazyComponent = useMemo(() => React.lazy(() => import(component)), [
    component
  ]);

  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent parentUpdate={parentUpdate} />
    </Suspense>
  );
};

谢谢,看起来不错!在阅读有关useMemo的文章时,facebook似乎暗示useMemo无法保证保留这些值。你觉得用Ref代替它怎么样?或者甚至是一个全局变量来保存已经加载的组件?这是一个很好的观点。您所需要的只是某种缓存机制。我已经使用Map添加了一个,但是您也可以使用lodash/memoize或任何其他缓存机制。
const DynamicLoader = ({ component, parentUpdate }) => {
  const LazyComponent = useMemo(() => React.lazy(() => import(component)), [
    component
  ]);

  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent parentUpdate={parentUpdate} />
    </Suspense>
  );
};
const componentsMap = new Map();

const getCachedLazy = component => {
  if (componentsMap.has(component)) return componentsMap.get(component);

  const Component = React.lazy(() => import(component));

  componentsMap.set(component, Component);

  return Component;
};

const DynamicLoader = ({ component, parentUpdate }) => {
  const LazyComponent = getCachedLazy(component);

  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent parentUpdate={parentUpdate} />
    </Suspense>
  );
};