英文:
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/Genre1
,MoviePage/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 () => {
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", // <-- add route id
path: "movies",
element: <Root2 />,
loader: movieLoader, // <-- promote loader
children: [
{ index: true, element: <MoviePage /> },
{ path: "Genre1", element: <Genre1 /> },
{ path: "Genre2", element: <Genre2 /> },
{ path: "Genre3", element: <Genre3 /> },
{ path: ":genre/:movieId", element: <MovieDetail /> },
],
},
],
},
]);
In any of the genre components, use the useRouteLoaderData
hook and provide the appropriate route id.
const movieData = useRouteLoaderData("movies");
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论