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

React Router v6.9.0中useLoaderData能否在兄弟组件使用及实现方案

问题解答

关于useLoaderData的使用范围

没错,useLoaderData只能在配置了对应loader的路由所渲染的组件,以及该组件的所有后代组件中使用。你这里的Genre1、Genre2是和MoviePage同级的路由组件,属于不同的路由分支,既不是MoviePage的后代,自身也没有配置loader,所以调用useLoaderData自然会返回undefined。

让Genre组件获取loader数据的几种方案

方案1:将loader移到父路由

把数据请求的loader配置到/movies对应的父路由(也就是Root2所在的路由),这样所有子路由的组件(包括MoviePage、Genre1、Genre2等)都能直接通过useLoaderData拿到数据。

修改后的路由示例:

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      {
        index: true,
        element: <HomePage />,
      },
      {
        path: "movies",
        element: <Root2 />,
        // 把loader移到父路由
        loader: async () => {
          const options = {
            method: "GET",
            url: "https://ott-details.p.rapidapi.com/advancedsearch",
            params: {
              start_year: "1970",
              end_year: "2020",
              min_imdb: "6",
              max_imdb: "10",
              genre: "action",
              language: "english",
              type: "movie",
              sort: "latest",
              page: "1",
            },
            headers: {
              "X-RapidAPI-Key": "{api-key}",
              "X-RapidAPI-Host": "ott-details.p.rapidapi.com",
            },
          };

          try {
            const response = await axios.request(options);
            return response.data;
          } catch (err) {
            console.error("数据请求失败:", err);
            throw new Response("加载失败", { status: 500 });
          }
        },
        children: [
          {
            index: true,
            element: <MoviePage />,
            // 移除这里的loader
          },
          { path: "Genre1", element: <Genre1 /> },
          { path: "Genre2", element: <Genre2 /> },
          { path: "Genre3", element: <Genre3 /> },
          { path: ":genre/:movieId", element: <MovieDetail /> },
        ],
      },
    ],
  },
]);

方案2:用useRouteLoaderData指定获取目标路由的loader数据

给配置了loader的MoviePage路由添加一个唯一id,然后在Genre组件中通过useRouteLoaderData(id)来获取该路由的loader返回值。

步骤1:修改路由,给MoviePage的路由加id:

{
  index: true,
  element: <MoviePage />,
  id: "movieListLoader", // 添加唯一id
  loader: async () => {
    // 原loader逻辑
  },
}

步骤2:在Genre组件中调用:

import { useRouteLoaderData } from "react-router-dom";

function Genre1() {
  const movieData = useRouteLoaderData("movieListLoader");
  // 接下来就可以使用movieData了
  return <div>{/* 渲染内容 */}</div>;
}

方案3:给每个Genre路由单独配置loader(更贴合业务场景)

如果不同Genre需要对应不同类别的电影数据,更合理的做法是给每个Genre路由配置自己的loader,根据genre参数请求对应数据。

示例:

{
  path: "Genre1",
  element: <Genre1 />,
  loader: async () => {
    const options = {
      // ... 基础配置
      params: {
        // ... 其他参数
        genre: "action", // 这里换成Genre1对应的类别
      },
    };
    try {
      const response = await axios.request(options);
      return response.data;
    } catch (err) {
      console.error(err);
      throw new Response("加载失败", { status: 500 });
    }
  },
}

额外提示:修正loader中的响应判断逻辑

你当前的loader里用!response.ok判断请求状态是错误的——axios的响应对象里没有ok属性,它会在请求失败(状态码≥400)时直接抛出异常,所以应该用try/catch包裹请求逻辑,更符合axios的使用规范,如上面方案中的代码所示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:17:16