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会看到一个新组件(不是同一个对象),卸载前一个组件,然后装载到新组件
要解决此问题,请使用insideDynamicLoader
来记忆当前的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>
);
};