30天入坑React ---------------day17 Client-Side-Routing
这篇文章是30天React系列的一部分 。
在本系列中,我们将从非常基础开始,逐步了解您需要了解的所有内容,以便开始使用React。如果您曾经想学习React,那么这里就是您的最佳选择!
客户端路由
大多数(如果不是全部)应用程序在我们的单页应用程序中都有多个视图。让我们直接使用React Router为我们的应用程序创建多个视图。
我们已经完成了16天了!拍拍你自己...但不要太久......还有很多。
现在,我们的应用程序仅限于一个页面。很难找到任何显示单个视图的复杂应用程序。例如,应用程序可能具有用户可以登录的登录视图,或者具有向用户显示其搜索结果列表的搜索结果页面。这是两个不同的视图,具有两个不同的页面结构。
让我们看看今天如何通过我们的应用程序改变它。
我们将使用非常流行的react-router库来处理不同的链接。为了使用该react-router
库,我们需要使用npm
包管理器安装它:
npm install --save react-router-dom
随着react-router
安装,我们会从库中导入了几个package包和更新我们的应用程序架构。在我们进行这些更新之前,让我们退一步,从高层次看看我们如何以及为什么以这种方式构建我们的应用程序。
从概念上讲,我们已经看到了如何使用组件和嵌套组件创建树结构。使用带有路径的单页面应用程序的这个透视图,我们可以将页面的不同部分视为子项。从这个角度来看,单页面应用程序中的路由是我们可以将子树的一部分用另一个子树切换出来的想法。然后我们可以在浏览器中动态切换出不同的树。
换句话说,我们将定义充当一个阵营部件根的可路由元件的组件。然后我们可以告诉React更改一个视图,它可以将整个React组件替换为另一个视图,就像它是由服务器呈现的完全不同的页面一样。
我们将使用我们的App
组件并定义我们可以在此App
组件中的应用程序中创建的所有不同路由。我们需要从react-router
包中提取一些组件。我们将用于设置此结构的这些组件如下:
<BrowserRouter />
/ <Router />
这是我们用来定义根或路由树的组件。该<BrowserRouter />
组件是React将在每个路由的基础上替换它的子组件的组件。
<Route />
我们将使用该<Route />
组件创建在网址上可用的特定位置可用的路线。该<Route />
组件安装在页面URL上,该URL与路由配置中设置的特定路由相匹配props
。
处理客户端导航的一种较旧的兼容方法是使用#
表示应用程序端点的(哈希)标记。我们将使用这种方法。我们需要导入这个对象来告诉浏览器这是我们想要处理导航的方式。
从我们几天前创建的应用程序的根目录开始,让我们更新我们src/App.js
的导入这些模块。我们将BrowserRouter
通过ES6使用不同的名称语法导入:
import React from 'react';
import {
BrowserRouter as Router,
Route
} from 'react-router-dom'
export default class App extends React.Component {
render() {
<Router>
{/* routes will go here */}
</Router>
}
}
现在让<Router />
我们使用我们在render()
函数中导入的组件在DOM中定义路由根。我们将使用history
prop 定义我们正在使用的路由类型。在此示例中,我们将使用通用兼容的哈希历史记录类型:
export default 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>
)
}
}
在浏览器中加载此页面,我们可以看到我们在根网址获取单一路由。不是很令人兴奋。让我们添加第二条路线,在/about
URL上显示一个关于页面的信息。
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom'
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 />
组件需要一个被调用的prop to
来指向我们想要呈现的客户端路由。让我们更新Home
和About
组件来使用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 />
组件将仅呈现它找到的第一个匹配路由。让我们更新我们的组件以使用该Switch
组件。由于react路由器将尝试呈现两个组件,我们需要指定我们只想exact
在根组件上进行匹配。
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>
)
}
}
显示视图
Althogh这是一个有限的介绍,我们不能讨论处理反应路由器而不谈论我们可以获得子组件的不同方式。
我们已经看到了使用component
prop 的最简单方法,但是有一个更强大的方法使用了一个名为prop的方法render
。该render
道具有望成为一个将与被调用函数match
与沿对象location
和路由配置。
该render
道具可以让我们呈现什么,我们希望在一个subroute,其中包括渲染等航线。狡猾,恩?让我们看看这个行动:
import React from 'react';
import {
BrowserRouter as Router,
Route,
Link,
Switch
} from 'react-router-dom'
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>
)
}
}
export default App;
现在我们的应用程序中有多个页面。我们已经研究了如何通过嵌套组件渲染这些路由,只需要几个导出react-router
。
react-router
提供了更多功能,我们没有时间介绍我们的快速路由介绍。更多信息请访问:
明天,我们将开始与Redux集成。这是我们开始集成更复杂数据处理的地方。
学习REACT正确的方法
React和朋友的最新,深入,完整的指南。
下一章:
Flux简介
本教程系列的完整源代码可以在GitHub repo上找到,其中包括所有样式和代码示例。
如果您在任何时候感到困难,还有其他问题,请随时通过以下方式与我们联系:
- 在文章末尾评论这篇文章
- 通过[email protected]发送电子邮件给我们
- 加入我们的gitter室
- 发送电子邮件至@fullstackreact