Remix v2.8.1根错误边界导致useRouteLoaderData返回undefined
Remix v2.8.1 父级Loader数据在错误边界丢失的原因与修复
原因分析
当给root路由添加DefaultErrorBoundary后,子路由触发错误时,Remix会切换到错误边界的渲染上下文。此时useRouteLoaderData('root')无法正常获取父级loader数据,是因为错误边界的渲染逻辑会隔离常规路由数据的上下文传递,导致该钩子无法读取到已执行完成的root loader返回值。
修复方案
方案1:在Nav组件中改用useMatches获取数据
useMatches能获取所有已成功匹配的路由数据(只要root的loader执行成功,就能拿到对应数据),直接在Nav内部通过这个钩子提取root数据:
import { useMatches } from "@remix-run/react"; export function Nav() { const matches = useMatches(); // 定位到id为root的路由匹配项 const rootMatch = matches.find(match => match.id === "root"); // 取出defer包装的loader数据 const rootData = rootMatch?.data; // 处理数据可能为undefined的场景(比如root自身loader出错时) if (!rootData) { return <nav>加载中或数据异常</nav>; } // 正常渲染导航内容 return ( <nav> {/* 使用rootData中的数据渲染 */} </nav> ); }
方案2:在错误边界中主动传递root数据
如果不想修改Nav组件的数据源,可以在root的DefaultErrorBoundary的fallback函数里,通过useMatches拿到root数据后传递给Nav:
import { DefaultErrorBoundary, useMatches, Outlet } from "@remix-run/react"; import { Nav } from "~/components/Nav"; export default function Root() { return ( <html> <body> <DefaultErrorBoundary fallback={() => { const matches = useMatches(); const rootData = matches.find(m => m.id === "root")?.data; return ( <> <Nav rootData={rootData} /> <div className="error">页面出错,请稍后重试</div> </> ); }} > <Nav /> <Outlet /> </DefaultErrorBoundary> </body> </html> ); }
同时修改Nav组件接收props传入的rootData:
import { useRouteLoaderData } from "@remix-run/react"; import type { rootLoader } from "~/root"; export function Nav({ rootData }: { rootData?: Awaited<ReturnType<typeof rootLoader>> }) { // 优先使用props传入的数据,无数据时用useRouteLoaderData兜底 const data = rootData ?? useRouteLoaderData("root"); // 后续渲染逻辑不变 }
额外注意
如果root路由自身的loader抛出错误,useMatches也无法获取到root数据,这种情况需要在root的loader中做错误捕获,或者在错误边界里添加对应的降级渲染逻辑。
内容的提问来源于stack exchange,提问作者BigChungus
相关产品推荐
相关产品推荐

