gpt4 book ai didi

javascript - React Router如何递归地创建页面?

转载 作者:行者123 更新时间:2023-11-29 15:11:07 25 4
gpt4 key购买 nike

我在这里谈论这个例子:https://reacttraining.com/react-router/web/example/recursive-paths

import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

const PEEPS = [
{ id: 0, name: "Michelle", friends: [1, 2, 3] },
{ id: 1, name: "Sean", friends: [0, 3] },
{ id: 2, name: "Kim", friends: [0, 1, 3] },
{ id: 3, name: "David", friends: [1, 2] }
];

function find(id) {
return PEEPS.find(p => p.id == id);
}

function RecursiveExample() {
return (
<Router>
<Person match={{ params: { id: 0 }, url: "" }} />
</Router>
);
}

function Person({ match }) {
let person = find(match.params.id);

return (
<div>
<h3>
{person.name}
’s Friends
</h3>
<ul>
{person.friends.map(id => (
<li key={id}>
<Link to={`${match.url}/${id}`}>{find(id).name}</Link>
</li>
))}
</ul>
<Route path={`${match.url}/:id`} component={Person} />
</div>
);
}

export default RecursiveExample;

在此示例中,我了解了递归如何一次完成一个步骤。让我感到困惑的是,什么时候(在那个小型浏览器中)如果我在刷新页面, /1/0/3/2/3/2或任何其他嵌套的示例后直接放置此链接,React Router如何知道以正确的顺序渲染组件。没有带有match + /:id1/:id2/:id3等的明确路由路径。

我知道这是不可行的,因为它可以达到无穷远,但是React Router如何解决这个问题?

最佳答案

TLDR; 此处的主要技巧是,只要所呈现的PersonRoute与URL匹配,保存pathRoute组件就会每次进行呈现。

详细信息

根据设计,仅当Route的component Prop 与页面的URL匹配时,才会呈现传递到Route的path Prop 的组件。

{/* Something will get rendered when the URL /whatever matches the URL of the page */}
<Route path="/whatever" component={Something}>

由于我们仅在单击时呈现嵌套的 Person(具有自己的 Route),因此我们可以无限期地生成这些递归路由。

每次呈现 Person时,都会在其中呈现一个 Route,作为下一个 Person的占位符。
function Person({ match }) {
// ...

return (
<div>
{/* ... */}
{/* this route is a placeholder for the next Person */}
<Route path={`${match.url}/:id`} component={Person} />
</div>
);
}

如果其下一个 PersonRoute与URL相匹配,则呈现此下一个 path。拥有的 Routepath是父级的URL加上另一个ID(即 match.url + '/:id')。

这就是我们获得递归渲染的方式。 Person呈现 Route,呈现 Person,呈现 Route ...重复此过程,直到最后呈现的 Routepath与页面URL不匹配。

注意: match prop通过 Route传递到作为 component Prop 传递到该 Route的组件中。这是 Person对其进行访问的方式。

需要注意的一件事:该应用程序始终以 Michelle的 friend (即 id0的人的 friend )开头,原因如下:
function RecursiveExample() {
return (
<Router>
{/* This part of the code passes in a fake `match` prop to always start of the app from Michelle's point of view */}
<Person match={{ params: { id: 0 }, url: "" }} />
</Router>
);
}

这意味着无论您是第一次打开页面还是在 /0/1/2处刷新页面,React Router始终将 Michelle呈现为第一个 Person,它将呈现嵌套的 <Route path='/:id' component={Person} />

这意味着应用程序的初始状态始终如下所示:
<RecursiveExample>
<BrowserRouter>
<Person>
<Route path="/:id" />
</Person>
</BrowserRouter>
</RecursiveExample>

呈现为:

app always starts with friends of Michelle

如果应用程序以 /加载,则渲染将在上述状态下停止,直到我们开始与应用程序进行交互为止。

但是,如果我们在 /0/1/2刷新页面,则渲染将继续。呈现以上所示的初始状态后,React Router将发现 path中的 <Route path="/:id" />/0/1/2 URL匹配(通过使 0忽略其余部分),将 id填充为 0并呈现下一个 Person(将 id用作 0)。 。

注意:上面的URL匹配之所以有效,是因为 Route的默认匹配策略是忽略路径末尾的任何多余字符。这就是 /:id/0/1/2匹配, id0/1/2部分被忽略的原因。我们可以使用 exact prop强制匹配完全正确,但是这将破坏递归行为,即 /:id仅匹配 /0而不匹配 /0/1/2

此时,我们的树看起来像:
<RecursiveExample>
<BrowserRouter>
<Person>
<Route path="/:id" {/* this matches /0 */}
<Person>
{/* we're here during the rendering stage */}
</Person>
</Route>
<Person>
</BrowserRouter>
</RecursiveExample>

在这个阶段渲染的人碰巧又是 Michelle(因为 id 0)。

Second stage also shows friends of Michelle

现在,此 Person重复该过程。它呈现自己的嵌套 Route,现在将 path作为 /0/:id(因为它将 /:id连接到父URL),然后再次将 component作为 Person。由于 /0/:id仍然与 /0/1/2(ID现在为 1)匹配,因此我们渲染下一个 Person

此时树是:
<RecursiveExample>
<BrowserRouter>
<Person>
<Route path="/:id" {/* this matches /0 */}
<Person>
<Route path="/0/:id"> {/* this matches /0/1 */}
<Person>
{/* we're here during the rendering stage */}
</Person>
</Route>
</Person>
</Route>
<Person>
</BrowserRouter>
</RecursiveExample>

现在,树显示了 id等于 1的人的 friend :

Now we show friends of Sean

你能看到这是怎么回事吗?

重复此过程,直到最后渲染的 path中呈现的 RoutePerson与URL不匹配为止。在刷新 /0/1/2 URL的情况下,这将是 Routepath /0/1/2/:id

这是最终的React树的外观:
<RecursiveExample>
<BrowserRouter>
<Person>
<Route path="/:id" {/* this matches /0 */}
<Person>
<Route path="/0/:id"> {/* this matches /0/1 */}
<Person>
<Route path="/0/1/:id"> {/* this matches /0/1/2 */}
<Person>
<Route path="/0/1/2/:id" /> {/* this isn't matched yet */}
</Person>
</Route>
</Person>
</Route>
</Person>
</Route>
<Person>
</BrowserRouter>
</RecursiveExample>

这是最终的应用程序状态:

final rendered state

现在,无论我们实际刷新页面 /0/1/2还是单击链接进行访问,其行为都是相同的。

重要的是要记住,它是控制呈现内容的URL。

通过刷新或手动键入特定URL来启动应用程序时,只要每个渲染路径的路径与URL匹配,React Router都会自动执行嵌套的 Person渲染阶段(如上所示)。

另一方面,每次单击指向特定URL的链接时,我们都会手动触发URL更改,从而触发下一个 Person的呈现阶段。

无论是手动键入URL还是通过单击创建URL,如果结果URL相同,则呈现的应用程序也相同。
不同之处在于我们如何达到最终的渲染状态。

关于javascript - React Router如何递归地创建页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54507619/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com