我目前正在学习动态响应路由。在我的示例代码中,我为每个工作设置了不同的按钮。当单击按钮时,它必须呈现WorkDetails
组件。然而,即使我手动更改URL slug,它也不会这样做。我很难找出哪里出了问题。
代码和框:https://codesandbox.io/s/dynamic-routes-budulp?file=/src/App.js
这是我的应用程序组件中的路线
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/works" element={<Work data={data} />}>
<Route path=":slug" element={<WorkDetails />} />
</Route>
</Routes>
</BrowserRouter>
在我的Work
组件中,每个按钮都用Link
包围。对于路径,我使用了数据文件中对象数组中的slug
。
const Work = ({ data }) => {
return (
<div>
<h1>Works</h1>
{data.map(({ id, name, slug }) => {
return (
<div key={id} id={id}>
<h2>{name}</h2>
<Link to={slug}>
<button>Work Details</button>
</Link>
</div>
);
})}
</div>
);
};
data.js
let works = [
{
id: 1,
name: "Work 1",
slug: "work-one",
subtopics: [
{
title: "About the project",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
},
{
title: "Process",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
},
{
title: "Result",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
}
]
},
{
id: 2,
name: "Work 2",
slug: "work-two",
subtopics: [
{
title: "About the project",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
},
{
title: "Process",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
},
{
title: "Result",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
}
]
},
{
id: 3,
name: "Work 3",
slug: "work-three",
subtopics: [
{
title: "About the project",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
},
{
title: "Process",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
},
{
title: "Result",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
}
]
},
{
id: 4,
name: "Work 4",
slug: "work-four",
subtopics: [
{
title: "About the project",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
},
{
title: "Process",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
},
{
title: "Result",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Sagittis orci a scelerisque purus semper eget duis at. Sodales neque sodales ut etiam sit amet. Proin sed libero enim sed faucibus turpis in eu mi. Blandit libero volutpat sed cras ornare arcu dui. Urna nunc id cursus metus. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Curabitur gravida arcu ac tortor. Natoque penatibus et magnis dis parturient montes nascetur. Aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Aenean sed adipiscing diam donec adipiscing."
}
]
}
];
在我的WorkDetails
组件上,我使用了useParams()
,我希望它返回slug
。然后,我使用slug
查找具有相同slug
的对象。然后,状态将用找到的对象更新。
const WorkDetails = () => {
const { slug } = useParams();
// Find the object with the same slug as the params.
const [work, setWork] = useState(null);
let findWork = data.find((d) => d.slug === slug);
if (findWork) {
setWork(findWork);
}
return (
<div>
<Link to="/works">
<button>Back to Works</button>
</Link>
<h1>{work.name}</h1>
{work.subtopic.map((topic) => {
return (
<>
<h2>{topic.title}</h2>
<p>{topic.description}</p>
</>
);
})}
</div>
);
};
4条答案
按热度按时间00jrzges1#
将app.js中的代码更改为
以及这条线
<Link to={slug}>
到这条线<Link to={
${slug}}>
和工作细节
lmyy7pcs2#
将工作详细信息文件更改为
ruyhziif3#
有几个问题:
1.路由的顺序不正确,应该是从特定到一般。
1.此外,在工作详细信息中,您设置的变量不正确。
我已经为你调整了你的例子,见下文。
https://codesandbox.io/s/dynamic-routes-forked-7j026p
qyzbxkaa4#
个问题
WorkDetails
组件呈现在***嵌套***路由上,因此为了呈现在"/works"
上呈现的父Work
组件,必须为嵌套路由呈现Outlet
组件,以便将其element
内容呈现到其中。另一个问题是,
WorkDetails
发布状态更新是无意的副作用。事实上,work
状态是完全不必要的,因为它能够从当前slug
路由路径参数值和工作项的data
数组中派生。它是一个将派生的“状态”存储在React状态中的React反模式。Filter/从data
数组中找到匹配的工作项,如果需要,通过useMemo
挂接记住该值,而不是存储在任何状态中。溶液
布局嵌套路线(& N)
如果要使用
Work
作为布局路线,则还应呈现Outlet
组件,以便嵌套路线将其内容呈现到其中。示例:
第一个
常规路线
如果您想将
Work
和WorkDetails
呈现为两个单独的路由和组件,则可以取消嵌套路由。呈现WorkDetails
不需要Outlet
组件。示例:
WorkDetails
应计算并呈现派生的“状态”WorkDetails
组件不应将派生的工作项值存储到本地状态中,而应直接计算并呈现搜索结果。示例:
如果需要记忆派生状态,则使用
useMemo
挂接: