使用React路由器的递归路径

目录
文章目录隐藏
  1. {person.name}’s Friends
  2. {person.name}’s Friends
  3. {person.name}’s Friends

  因为 ReactRouter 只是组件,你可以做一些疯狂的事情,比如递归路由。在这篇文章中,我们将通过分解 ReactRouter 文档中的“递归路径”示例来了解它们是如何工作的。

使用 React 路由器的递归路径

  递归路由不是世界上最实用的东西,但它们确实展示了 ReactRouter 基于组件的路由方法的好处。

  这里的主要思想是,由于 React Router 只是组件,理论上,你可以为无限路由创建递归路由。秘密就在于建立正确的数据结构,这可以导致无限的路由。在本例中,我们将使用具有 id、名称和朋友数组的人员数组。

const users = [
  { 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 ] }
]

  通过以这种方式设置这个数据结构,当我们呈现一个人时,我们将呈现他们所有的朋友作为链接。然后,当一个链接被点击时,我们将把那个人的所有朋友都呈现为链接,以此类推。每次点击一个链接,应用程序的路径名就会逐渐变长。

  最初,我们会看到/,UI 是这样的

Michelle's Friends

  * Sean
  * Kim
  * David

  如果单击 Kim,那么 URL 将变为/2(Kim 的 ID),UI 将如下所示

Michelle's Friends

  * Sean
  * Kim
  * David

Kim's Friends

  * Michelle
  * Sean
  * David

  如果单击 David,那么 URL 将变为/2/3(Kim 的 id 和 David 的 id),UI 将像这样

Michelle's Friends

  * Sean
  * Kim
  * David

Kim's Friends

  * Michelle
  * Sean
  * David

David's Friends

  * Sean
  * Kim

  只要用户想点击链接,这个过程就会一直重复。

  一旦你建立了正确的数据结构,下一个重要步骤是继续呈现路由和一些链接。因为我们正在创建无限的路由,所以我们需要确保每次单击链接时都会呈现一个路由。如果没有,我们将不会得到更多的匹配,这意味着 React Router 将不会呈现更多的组件。在我们的链接和路由中,我们需要知道应用程序的当前路径名,这样我们就可以在每次单击链接时追加它(就像在上面的例子中,我们从/2 到/2/3,等等)。幸运的是,React Router 为我们提供了带有 match.url 的路径名。考虑到这一点,链接的初始部分将是这样的

<link to="{'{match.url}/${id}}'">

  我们渲染的路径会在相似的模式下匹配,然后渲染相同的组件。

<Route path={'${match.url}/:id'} component={Person}/>

  现在我们已经了解了基础知识,让我们开始构建将被递归呈现的组件 Person。

  请记住,这个组件需要负责一些事情。

  1.它应该为每个特定的人的朋友呈现一个 Link 组件。

  2.它应该呈现与当前路径名+/:id 匹配的路由组件。

  与所有递归问题一样,我们需要以某种方式“开始”递归。通常这涉及到调用函数,但是如果它是递归调用的组件,我们可以通过简单地创建元素来实现。

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

const users = [
  { 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 ] }
]

const Person = ({ match }) => {
  return (
    
PERSON
) } class App extends React.Component { render() { return ( ) } } export default App

  现在我们需要做的是找出如何从用户数组中获取特定朋友的信息,这样我们就可以获取他们的名字并呈现他们的朋友。在这里大家可能会注意到这里有一个问题。最终 Person 会被路由器渲染,它会被传递一个属性匹配。我们将使用这个匹配道具获取当前路径名和(在用户的帮助下)人名和好友列表。问题是我们在主 App 组件中手动渲染 Person 来启动递归。这意味着匹配将在第一次呈现 Person 时未定义。这个问题的解决办法比看上去简单。当我们第一次手动渲染时,我们需要像路由器那样给它传递一个属性匹配。

class App extends React.Component {
  render() {
    return (
      
        
      
    )
  }
}

  现在,每次渲染 Person 时,包括第一次,它都会被传递一个匹配属性,这个属性包含我们需要的两个东西,url 来渲染我们的路由,链接和参数。id,这样我们就能知道渲染的是谁。

  好了,回到我们的主要目标。Person 需要

  1、它应该为每个特定的人的朋友呈现一个 Link 组件。

  2、它应该呈现与当前路径名+/:id 匹配的路由组件。

  在我们能够呈现任何链接之前,我们需要得到这个人的朋友。我们已经从 match.params.id 中知道了这个人的 id。在数组中我们可以直接通过使用 Array.find 方法获取朋友的信息。我们将为它创建一个辅助函数。

const users = [
  { 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 ] }
]

const find = (id) => users.find(p => p.id == id)

const Person = ({ match }) => {
  const person = find(match.params.id)

  return (
    
PERSON
) }

  现在我们有了 person,让我们呈现一些包括每个朋友的链接的 UI。

const users = [
  { 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 ] }
]

const find = (id) => users.find(p => p.id == id)

const Person = ({ match }) => {
  const person = find(match.params.id)

  return (
    

{person.name}’s Friends

    {person.friends.map((id) => (
  • {find(id).name}
  • ))}
) }

  现在我们已经为每个人的朋友建立了一个链接,如第 2 条所述,我们需要确保我们也呈现了一个路由。

const Person = ({ match }) => {
  const person = find(match.params.id)
  return (
    

{person.name}’s Friends

    {person.friends.map((id) => (
  • {find(id).name}
  • ))}
) }

  完整的代码现在看起来是这样的

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

const find = (id) => users.find(p => p.id == id)

const users = [
  { 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 ] }
]

const Person = ({ match }) => {
  const person = find(match.params.id)

  return (
    

{person.name}’s Friends

    {person.friends.map((id) => (
  • {find(id).name}
  • ))}
) } class App extends React.Component { render() { return ( ) } } export default App

  第一次呈现 Person 时,我们向它传递一个模拟匹配对象。然后,Person 呈现链接列表以及匹配这些链接的路由。当单击链接时,该路由与呈现另一个 Person 组件的路由匹配,后者呈现链接列表和新路由。理论上,只要用户继续点击任何链接,这个过程就会一直持续下去。

「点点赞赏,手留余香」

2

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » 使用React路由器的递归路径

1 评论

  1. 学习了,感谢分享

回复 潇潇尓 取消回复