Ash*_*sha 5 lazy-loading reactjs react-router react-hooks
我有以下组件可以在需要时加载我的组件(在路线更改时)。
function DynamicLoader(props) {
const LazyComponent = React.lazy(() => import(`${props.component}`));
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}
Run Code Online (Sandbox Code Playgroud)
我的路由(使用 React-Router)如下所示:
<Switch>
{routes.map((prop, key) => {
return (
<Route
exact
path={prop.path}
render={() => (
<DynamicLoader component={prop.component} />
)}
key={key}
/>
);
})}
</Switch>
Run Code Online (Sandbox Code Playgroud)
就为每个路由安装组件而言,这工作正常,但是看起来随着父组件的每次更改,React 正在卸载并重新安装延迟加载的组件(而不是重新渲染)。这会导致所有内部状态重置,这当然是不希望的。任何人都可以推荐任何解决方案吗?这是一个显示此问题的代码和框。
Ori*_*ori 11
每当渲染父级时,都会DynamicLoader重新创建LazyComponent. React 看到一个新组件(不是同一个对象),卸载前一个组件,然后安装到新组件。
要解决此问题,请使用React.useMemo()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>
);
};
Run Code Online (Sandbox Code Playgroud)
沙箱- 为了展示 memoized LazyComponent,我将外部传递update给HomeA组件。
由于useMemo()无法保证缓存(React 可能会不时释放内存),因此您可以使用以下方法编写一个简单的延迟缓存Map:
const componentsMap = new Map();
const useCachedLazy = (component) => {
useEffect(
() => () => {
componentsMap.delete(component);
},
[component]
);
if (!componentsMap.has(component)) {
componentsMap.set(
component,
React.lazy(() => import(component))
);
}
return componentsMap.get(component);
};
const DynamicLoader = ({ component, parentUpdate }) => {
const LazyComponent = useCachedLazy(component);
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent parentUpdate={parentUpdate} />
</Suspense>
);
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2109 次 |
| 最近记录: |