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

React-Router Route Loader初始化加载时执行两次问题求助

问题描述

使用React-Router的route loader特性实现页面加载前数据预取时,遇到初始化页面加载时请求被执行两次的问题。通过Chrome的React Profiler扩展排查发现:App组件仅初始化渲染一次,但RouterProvider组件首次渲染后,会因包含loader数据的“hook 1”变化再次触发渲染,最终导致loader被重复执行。

复现代码如下:

const App = () => {
  const router = createBrowserRouter([
        {
          path: "/", element: <HomePage />,
          loader:  () => {
            return fetch(`google.com/services/homepage-tags`);
          },
        },
  ]);

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

export default App;
解决方案

问题根源

每次App组件渲染时都会重新调用createBrowserRouter生成全新的router实例。RouterProvider检测到router实例更新后,会重新初始化整个路由逻辑,自然会再次执行loader函数。

修复方法

方法1:将router实例创建移到组件外部

把router的创建逻辑放在App组件作用域之外,确保只会执行一次:

const router = createBrowserRouter([
  {
    path: "/", 
    element: <HomePage />,
    loader: () => {
      return fetch(`google.com/services/homepage-tags`);
    },
  },
]);

const App = () => {
  return <RouterProvider router={router} />;
};

export default App;

方法2:用useMemo缓存router实例

如果router的创建依赖组件内部的状态或props,使用useMemo缓存实例,仅在依赖项变化时重新创建:

import { useMemo } from 'react';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';

const App = () => {
  const router = useMemo(() => 
    createBrowserRouter([
      {
        path: "/", 
        element: <HomePage />,
        loader: () => {
          return fetch(`google.com/services/homepage-tags`);
        },
      },
    ]), 
    [] // 空依赖数组确保仅初始化时创建一次
  );

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

export default App;

修改后,router实例只会被创建一次,RouterProvider不会因实例变化重复渲染,loader也就只会执行一次。

内容的提问来源于stack exchange,提问作者Mohammad Ali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:58:20