Can useLoaderData be used in the sibling components of the component in which loader() is used in ReactRouter v6.9.0. If yes then how?

huangapple go评论81阅读模式
英文:

Can useLoaderData be used in the sibling components of the component in which loader() is used in ReactRouter v6.9.0. If yes then how?

问题

我已使用加载程序在我的 MoviePage 组件中获取了数据,并通过 useLoaderData 使用了这些数据。现在我想在兄弟组件中使用这些数据,比如 MoviePage/Genre1MoviePage/Genre2 等等。

为此,我尝试在兄弟组件中使用 useLoaderData,但结果被读取为 'undefined'。这是否意味着 useLoaderData 只能在加载程序已经使用的路由组件中使用?如果是的话,那么如何在其他 Genre 组件中使用返回的结果?

这是我的路由定义方式。

英文:

I have fetched data using loader in my MoviePage component and I am using this data by using useLoaderData. Now I want to use this data in sibling components like MoviePage/Genre1, MoviePage/Genre2 etc.
For this I am trying to use useLoaderData in the sibling components, but the result is being read as 'undefined'. Does this mean that useLoaderData can be used only in the route component in which loader has been used. If yes, then how can I use the result returned in the other Genre components?

This is how my routes are defined.

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />, // Wrapper Component
    children: [
      {
        index: true,
        element: <HomePage />,
      },
      {
        path: "movies",
        element: <Root2 />,
        children: [
          {
            index: true,
            element: <MoviePage />,
            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",
                },
              };

              const response = await axios.request(options);
              if (!response.ok) {
                return response.data;
              } else {
                console.log(response.status);
              }
            },
          },
          { path: "Genre1", element: <Genre1 /> },
          { path: "Genre2", element: <Genre2 /> },
          { path: "Genre3", element: <Genre3 /> },
          { path: ":genre/:movieId", element: <MovieDetail /> },
        ],
      },
    ],
  },
]);               

答案1

得分: 1

你可能希望使用 useRouteLoaderData 钩子,而不是 useLoaderData 钩子。

useRouteLoaderData

这个钩子使得在树中的任何当前渲染路由的数据都可以在任何地方使用。这对于深层嵌套在树中的组件需要来自更远处的路由的数据,以及需要子路由深层树中的数据的父路由都非常有用。

重要提示:只有在使用数据路由时才能使用此功能,参见 选择路由器

你可能只需要为路由提供一个 id 属性。你可能需要将加载程序函数提升到 MoviePage 和类型路由/组件的父布局路由,以便在嵌套路由更改时数据仍然可用。

const movieLoader = 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",
    },
  };

  const response = await axios.request(options);
  if (!response.ok) {
    return response.data;
  } else {
    console.log(response.status);
  }
}
const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      { index: true, element: <HomePage /> },
      {
        id: "movies", // <-- 添加路由id
        path: "movies",
        element: <Root2 />,
        loader: movieLoader, // <-- 提升加载程序
        children: [
          { index: true, element: <MoviePage /> },
          { path: "Genre1", element: <Genre1 /> },
          { path: "Genre2", element: <Genre2 /> },
          { path: "Genre3", element: <Genre3 /> },
          { path: ":genre/:movieId", element: <MovieDetail /> },
        ],
      },
    ],
  },
]);

在任何类型的组件中,使用 useRouteLoaderData 钩子并提供适当的路由id。

const movieData = useRouteLoaderData("movies");
英文:

You might be looking to use the useRouteLoaderData hook instead of the useLoaderData hook.

> useRouteLoaderData
>
> This hook makes the data at any currently rendered route available
> anywhere in the tree. This is useful for components deep in the tree
> needing data from routes much farther up, as well as parent routes
> needing the data of child routes deeper in the tree.
>
> > Important: This feature only works if using a data router, see
> > Picking a Router

You may only need to provide an id prop for the route. You may need to promote the loader function to the parent layout route of the MoviePage and genre routes/components. This is so the data remains available when the nested routes change.

const movieLoader  = async () =&gt; {
  const options = {
    method: &quot;GET&quot;,
    url: &quot;https://ott-details.p.rapidapi.com/advancedsearch&quot;,
    params: {
      start_year: &quot;1970&quot;,
      end_year: &quot;2020&quot;,
      min_imdb: &quot;6&quot;,
      max_imdb: &quot;10&quot;,
      genre: &quot;action&quot;,
      language: &quot;english&quot;,
      type: &quot;movie&quot;,
      sort: &quot;latest&quot;,
      page: &quot;1&quot;,
    },
    headers: {
      &quot;X-RapidAPI-Key&quot;: &quot;{api-key}&quot;,
      &quot;X-RapidAPI-Host&quot;: &quot;ott-details.p.rapidapi.com&quot;,
    },
  };

  const response = await axios.request(options);
  if (!response.ok) {
    return response.data;
  } else {
    console.log(response.status);
  }
},
const router = createBrowserRouter([
  {
    path: &quot;/&quot;,
    element: &lt;Root /&gt;,
    children: [
      { index: true, element: &lt;HomePage /&gt; },
      {
        id: &quot;movies&quot;, // &lt;-- add route id
        path: &quot;movies&quot;,
        element: &lt;Root2 /&gt;,
        loader: movieLoader, // &lt;-- promote loader
        children: [
          { index: true, element: &lt;MoviePage /&gt; },
          { path: &quot;Genre1&quot;, element: &lt;Genre1 /&gt; },
          { path: &quot;Genre2&quot;, element: &lt;Genre2 /&gt; },
          { path: &quot;Genre3&quot;, element: &lt;Genre3 /&gt; },
          { path: &quot;:genre/:movieId&quot;, element: &lt;MovieDetail /&gt; },
        ],
      },
    ],
  },
]);

In any of the genre components, use the useRouteLoaderData hook and provide the appropriate route id.

const movieData = useRouteLoaderData(&quot;movies&quot;);

huangapple
  • 本文由 发表于 2023年3月12日 10:32:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75710772.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定