You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首页Loader重定向时出现无限循环问题求助

路由Loader触发无限循环的原因及修复方案

我希望提前预取部分数据,编写了如下路由与Loader逻辑,但出现了无限循环问题,恳请告知问题原因及修复方案。

问题代码

homeLoader函数

homeLoader: async (queryClient) => {
  queryClient.ensureQueryData(['someKey'], doSomething);
  return redirect(`workspaces/1`); // 此处触发无限循环
}

路由配置

createBrowserRouter(
  createRoutesFromElements(
    <Route
      path='/'
      element={<Home />}
      loader={() => homeLoader(queryClient)} // 已注入React Query
    >
      <Route path='workspaces' element={<Workspaces />}>
        <Route path=':workspaceId' element={<Workspace />} />
      </Route>
    </Route>
  )
)

<RouterProvider router={router} />

依赖版本

"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.2"

问题原因

  • 根路由/的loader执行时,调用redirect('workspaces/1')触发路由导航到/workspaces/1
  • 由于/workspaces/1是根路由/的子路由,React Router加载子路由前会强制执行所有父路由的loader
  • 这就导致每次导航到/workspaces/1时,都会重复执行根路由的loader,loader再次触发redirect,形成无限循环

修复方案

方案1:将预取逻辑移到目标子路由

如果预取的数据是/workspaces/1所需,直接在该子路由的loader中执行预取,同时移除根路由的redirect逻辑:

// 修改子路由配置
<Route path='workspaces' element={<Workspaces />}>
  <Route 
    path=':workspaceId' 
    element={<Workspace />}
    loader={() => workspaceLoader(queryClient)}
  />
</Route>

// 子路由对应的loader
const workspaceLoader = async (queryClient) => {
  await queryClient.ensureQueryData(['someKey'], doSomething);
  // 返回子路由业务所需数据,无数据则返回null
  return null;
};

方案2:在根路由loader中添加路径判断

通过loader参数获取当前请求路径,仅当不在目标路由时才执行redirect:

// 修改homeLoader,接收request参数
homeLoader: async ({ request }, queryClient) => {
  await queryClient.ensureQueryData(['someKey'], doSomething);
  const currentPath = new URL(request.url).pathname;
  // 补全绝对路径,避免相对路径导航异常
  const targetPath = '/workspaces/1';
  if (currentPath !== targetPath) {
    return redirect(targetPath);
  }
  return null;
}

// 路由loader调用时传递参数
loader={({ request }) => homeLoader({ request }, queryClient)}

方案3:应用初始化时预取数据

在应用入口组件中通过useEffect执行预取,根路由仅负责重定向:

// App组件示例
function App() {
  const queryClient = useQueryClient();
  useEffect(() => {
    // 使用prefetchQuery而非ensureQueryData,避免阻塞渲染
    queryClient.prefetchQuery(['someKey'], doSomething);
  }, [queryClient]);

  return <RouterProvider router={router} />;
}

// 根路由loader简化为
homeLoader: () => redirect('/workspaces/1');

内容的提问来源于stack exchange,提问作者Игор Ташевски

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:55:22