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

React Router DOM 6.14:元素与Loader传参及全局加载态问题

React Router DOM 6.14 两个问题的解决方案

问题1:向loader传递Context/组件数据(避免用params)

Loader函数在组件渲染前执行,没法直接用useContext,但可以通过在组件内部创建路由的方式,把Context数据作为参数传给loader:

  1. 新建路由配置组件,在组件内获取Context数据
// RouterConfig.tsx
import { useContext } from 'react';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import { SiteContext } from './hooks/useContext';
import App from './App';
import ErrorPage from './ErrorPage';
import ProductsMain from './ProductsMain';
import { getItems } from './getItems';

export const RouterConfig = () => {
  // 拿到Context里的数据
  const siteContext = useContext(SiteContext);

  const router = createBrowserRouter([
    {
      path: "/",
      element: <App />,
      errorElement: <ErrorPage />,
      children: [
        {
          path: "/products/:category",
          element: <ProductsMain />,
          // 把Context数据作为参数传给loader
          loader: (request) => getItems(request, siteContext),
        }
      ],
    }
  ]);

  return <RouterProvider router={router} />;
};
  1. 修改getItems函数接收额外参数
export async function getItems(request: any, contextData: any) {
  const body = {
    // 直接使用传递过来的Context数据
    ...contextData,
    // 其他需要的字段
  };
  try {
    const url = `${urlBE}/products/${request.params.category}`;
    return await serverAPI(url, body, "success");
  } catch (error: any) {
    throw new Error(error);
  }
}
  1. 更新Index.tsx使用新的路由组件
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import { RouterConfig } from "./RouterConfig";
import { SiteProvider } from "./hooks/useContext";

const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement);
root.render(
  <React.StrictMode>
    <SiteProvider>
      <RouterConfig />
    </SiteProvider>
  </React.StrictMode>
);

这样Context更新时,路由会重新创建,loader也能拿到最新的数据。

问题2:全局实现loader加载动画

用React Router的useNavigation hook可以全局监听loader的加载状态,在根组件里统一处理:

  1. 修改根组件App(或者全局Layout组件)
import { useNavigation, Outlet } from 'react-router-dom';

function App() {
  const navigation = useNavigation();
  // 判断是否有loader正在加载
  const isLoading = navigation.state === 'loading';

  return (
    <div className="app-wrapper">
      {/* 全局加载动画 */}
      {isLoading && (
        <div className="global-spinner">
          <span>加载中...</span>
          {/* 这里可以替换成你的Spinner组件 */}
        </div>
      )}
      {/* 子路由内容 */}
      <Outlet />
    </div>
  );
}
  1. 给全局Spinner加样式(示例)
.global-spinner {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 18px;
  z-index: 9999;
}

只要任何路由的loader在请求数据,navigation.state就会变成loading,全局Spinner就会自动显示/隐藏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 14:07:44