React Router DOM 在頁面切換時,會有一定機會出現閃爍的情況。這邊筆記下搭配 lazy 延遲載入元件一同使用時,不會產生閃爍情況的寫法。
內容
關鍵點有兩個:用 async lazy() 和 redirect() 合用,程式碼內容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
import { FiList } from 'react-icons/fi'; import { MdEvent } from 'react-icons/md'; import { Navigate } from 'react-router-dom'; export const MODULE_A_ROUTES = { name: 'Module A', path: '/modulea', icon: MdEvent, async lazy() { const { Layout } = await import('@/layout'); return { Component: Layout }; }, children: [ { index: true, element: <Navigate to="/modulea/abc" replace={true} />, }, { path: 'abc', name: 'ABC', icon: FiList, async lazy() { const { Abc } = await import('@/pages/Event/Abc'); return { Component: Abc }; }, }, ], }; // index.ts export const DYNAMIC_ROUTES = [MODULE_A_ROUTES]; function generateRoutes(item){ const route = { path: item.path || '', element: item.element, lazy: item.lazy, }; route.children = item?.children?.map((child) => generateRoutes(child)) ?? []; if (item.index) { return { index: item.index, element: item.element, }; } return route; } export default createBrowserRouter([ { path: '/', element: <Layout />, children: [ { index: true, // Use redirect function to avoid page flickering loader: () => redirect('/modulea/abc'), }, ], }, ...DYNAMIC_ROUTES.map((i) => generateRoutes(i)), { path: '*', element: <div>No Match</div>, }, ]); |
參考資料
1. [Bug]: Redirecting synchronously/without flicker
2. react-router/examples/lazy-loading-router-provider/src /App.tsx
3. Lazy loading routes in react router v6