cmp*_*rog 5 reactjs react-router code-splitting react-router-dom
我正在开发一个应用程序,它使用默认的 React 代码分割,使用 Lazy/Suspense 方法和 React Router 进行组件渲染。目前,当我导航到另一个路径时,如果网速较慢,在获取组件时会更新路径并渲染回退组件,是否有办法在当前路径上等待组件包完全下载?
是的,在启用的并发模式下,您可以创建一个自定义路由器,以将历史对象上的useTransition()每个导航方法包装在悬念转换中:
import { useState, unstable_useTransition as useTransition } from 'react';
import { Router } from 'react-router-dom';
const SuspenseRouter = ({ children, history, ...config }) => {
const [startTransition, isPending] = useTransition(config);
const [suspenseHistory] = useState(() => {
const { push, replace, go } = history;
history.push = (...args) => {
startTransition(() => { push.apply(history, args); });
};
history.replace = (...args) => {
startTransition(() => { replace.apply(history, args); });
};
history.go = (...args) => {
startTransition(() => { go.apply(history, args); });
};
});
suspenseHistory.isPending = isPending;
return (
<Router history={suspenseHistory}>
{children}
</Router>
);
};
export default SuspenseRouter;
Run Code Online (Sandbox Code Playgroud)
示例用法可能如下所示:
import { Suspense, lazy, unstable_createRoot as createRoot } from 'react';
import { Switch, Route } from 'react-router-dom';
import { createBrowserHistory } from 'history';
import SuspenseRouter from './components/SuspenseRouter';
const history = createBrowserHistory();
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
<SuspenseRouter history={history} timeoutMs={2000}>
<Suspense fallback="Loading...">
<Switch>
<Route path="/" exact={true} component={Home} />
<Route path="/about" component={About} />
</Switch>
</Suspense>
</SuspenseRouter>
);
createRoot(document.getElementById('root')).render(<App />);
Run Code Online (Sandbox Code Playgroud)
如果您想在上一条路线上无限期等待,请设置timeoutMs为。Infinity在上面的示例中,将其设置为2000应在上一个路由上等待最多 2 秒,fallback如果此时尚未下载所请求路由的代码,则显示 。