2

本文转载自:众成翻译
译者:iOSDevLog
链接:http://www.zcfy.cc/article/3815
原文:https://www.fullstackreact.com/30-days-of-react/day-17/

大多数(如果不是全部)我们的应用将在我们的单页应用中有多个视图。让我们直接使用React Router为我们的应用创建多个视图。

我们已经做了16天了!轻拍你的后背.....。但不是太久, 还有很多。

现在, 我们的应用被限制在一个单一的页面。发现任何显示单个视图的复杂应用都非常少见。例如, 应用可能有一个登录视图, 用户可以在其中登录, 或者搜索结果页显示用户的搜索结果列表。这两种不同的视图具有两种不同的页面结构。

让我们看看我们如何可以改变与我们的应用今天。

我们将使用非常流行的 react-router 库来处理不同的链接。为了使用react-router 库, 我们需要使用 npm 包管理器来安装它:

npm install --save react-router-dom

安装了react-router , 我们将从库中导入一些软件包, 并更新我们的应用体系结构。在我们做这些更新之前, 让我们退后一步, 从高层看 howwhy 我们以这种方式构建我们的应用。

从概念上讲, 我们已经看到了如何使用组件和嵌套组件来创建树结构。使用带有路由的单个页面应用的这个视角(perspective), 我们可以将页面的不同部分视为子级。从这个角度来看, 单页应用中的路由是这样一种想法, 即我们可以使用一个子树的一部分并将它与另一个子树进行切换。然后, 我们可以 动态 在浏览器中切换出不同的树。

换言之_, 我们将定义一个React组件, 它充当可路由元素的 _根 组件。然后, 我们可以告诉React改变一个视图, 它可以只是交换一个整个React组件为另一个, 虽然它是一个完全不同的页面渲染的服务器。

我们将采取我们的App 组件, 并定义所有不同的路由, 我们可以在我们的应用在这个 App 组件。我们需要从react-router 包中提取一些组件。我们将用于设置此结构的这些组件如下:

<BrowserRouter /> / <Router />

这是我们用来定义 或路由树的组件。<BrowserRouter />组件是一个组件, 其中React将在每个路由的基础上取代它的孩子。

<Route />

我们将使用<Route />组件在 url 的特定位置创建可用的路由。<Route />组件 安装在与路由配置 属性 中设置的特定路由匹配的页面 url 中。

一个旧的、兼容的处理客户端导航的方法是使用表示应用端点的 # (hash) 标记。我们将使用此方法。我们需要导入这个对象来告诉浏览器这就是我们想要处理导航的方式。

从我们创建了几天前的根目录的应用, 让我们更新我们的 src/App.js 来导入这些模块。我们将使用不同的名称语法通过 ES6 导入 BrowserRouter :

import React from 'react';

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

export class App extends React.Component {

  render() {
    <Router>
      {/* routes will go here */}
    </Router>
  }

}

现在, 让我们在 DOM 中使用在render()函数中导入的 <Router />组件定义路由根,。我们将定义使用 history 属性的路由类型。在本例中, 我们将使用普遍兼容的哈希历史类型:

export class App extends React.Component {
  // ...
  render() {
    <Router>
      {/* routes will go here */}
    </Router>
  }
  // ...
}

现在, 让我们定义我们的第一条路由。要定义一个路由, 我们将使用 <Route />组件从react-router 导出, 并传递给它的几个属性:

  • path - 要激活的路由的路径

  • component -定义路由视图的组件

让我们在根路径 / 中定义路由, 并使用只显示一些静态内容的无状态组件:

const Home = () => (<div><h1>Welcome home</h1></div>)
  // ...
class App extends React.Component {
  render() {
    return (
      <Router>
        <Route path="/" component={Home} />
      </Router>
    )
  }
}

在浏览器中加载此页, 我们可以看到我们在根 url 处得到了一个路由。不是很使人激动。让我们添加第二条在/about URL 中显示关于页面的路由。

const Home = () => (<div><h1>Welcome home</h1></div>)
  // ...
class App extends React.Component {
  render() {
    return (
      <Router>
        <div>
          <Route path="/" component={Home} />
          <Route path="/about" component={About} />
        </div>
      </Router>
    )
  }
}

在我们看来, 我们需要添加一个链接 (或一个锚标记- <a />), 使我们的用户可以自由地在两个不同的路由之间旅行。但是, 使用 <a />标记将告诉浏览器处理路由, 就像服务器端路由一样。相反, 我们需要使用一个不同的组件 (意外), 称为: <Link />

<Link />组件需要一个称为to的属性, 指向要渲染的客户端路由。让我们更新 HomeAbout组件以使用Link:

const Home = () => (<div><h1>Welcome home</h1><Link to='/about'>Go to about</Link></div>)
const About = () => (<div><h1>About</h1><Link to='/'>Go home</Link></div>)

等一下...... 我们不太希望 二个路由都 出现。发生这种情况的原因是, 响应路由器将渲染与路径匹配的 所有 内容 (除非另有指定)。对于这种情况, 响应路由器为我们提供了 Switch组件。

<Switch />组件将 渲染它发现的第一个匹配 route_。让我们更新组件以使用 Switch组件。由于响应路由器将尝试渲染 _两个 组件, 因此我们需要指定我们只希望根组件上的 "精确" 匹配。

const Home = () => (<div><h1>Welcome home</h1><Link to='/about'>Go to about</Link></div>)
  // ...
class App extends React.Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route path="/about" component={About} />
          <Route path="/" component={Home} />
        </Switch>
      </Router>
    )
  }
}

显示视图

虽然这是一个有限的介绍, 我们不能离开讨论的处理react路由器, 而不谈我们可以得到不同的方式来渲染子组件。

我们已经看到了最简单的方式可能, 使用 component 属性, 但有一个更强大的方法使用的属性称为renderrender属性预计将是一个函数, 将在match 对象连同location 和路由配置时调用。

render 属性允许我们渲染 无论什么 我们想要在一个路由, 其中包括渲染其他路由。很漂亮吧?让我们来看看这个动作:

const Home = () => (<div><h1>Welcome home</h1><Link to='/about'>Go to about</Link></div>)
const About = ({ name }) => (<div><h1>About {name}</h1></div>)
  // ...
class App extends React.Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route
            path="/about"
            render={(renderProps) => (
              <div>
                <Link to='/about/ari'>Ari</Link>
                <Link to='/about/nate'>Nate</Link>
                <Route
                  path="/about/:name"
                  render={(renderProps) => (
                    <div>
                      <About name={renderProps.match.params.name} />
                      <Link to='/'>Go home</Link>
                    </div>
                  )} />
              </div>
            )} />
          <Route
            path="/"
            render={(renderProps) => (
              <div>
                Home is underneath me
                <Home {...this.props} {...renderProps} />
              </div>
            )} />
        </Switch>
      </Router>
    )
  }
}

现在我们的应用中有多个页面。我们已经研究了如何通过嵌套组件来渲染这些路由, 其中仅有几个来自react-router 的导出。

react-router 提供了这么多的功能, 我们没有时间来弥补在我们的快速介绍路由。有关详细信息, 可查看下面连接:

明天, 我们将开始与再现的整合。下面是我们开始集成更复杂数据处理的地方。


不想成熟的大叔
882 声望526 粉丝

为学习前端开发不再枯燥、困难和迷茫而努力。