设想,我们正在使用react构建一个单页应用(SPA),我们应该怎么设置路由呢?在页面没有刷新的情况下,要更改页面的某个部分或者整个页面,这时候就是使用前端路由的时候了。配合react构建SPA的路由框架非react-router莫属。react-router更新到4.0版本,其设计思想已经和前几个版本不一样。其设计的思路是”动态路由”。何为”动态路由”?就是路由发生在app的渲染过程中!那与之相对应的就是”静态路由”,静态路由是在应用初始化前就已经定义好路由信息。所以,从定义上看是完全不一样的,那在使用的过程中也会有很大差别。
接下来我们看看react-router是如何工作的?
- (1) 把<Router />组件放到应用的最顶层
- (2) 使用<Link />组件定义路由
- (3) 最后,使用<Route />组件展现路由对应的UI
如上,react-router会涉及到几个重要的组件,分别<是Router />、<Link />和<Route />,翻译过来就是路由组件、导航组件和路由匹配组件。实际上,react-router也就是由这三类组件组成,所有这些组件都可以从”react-router-dom”这个npm包中导入使用。
我们来看看路由组件<Router />,针对web应用,react-router提供了<BrowserRouter />和<HashRouter />。除了实现原理不一样外,使用上也有区别,<BrowserRouter />支持服务端渲染而<HashRouter />不支持,所以在使用的时候得注意这一点。
基于以上对react-router的简单认识,我们来把它使用起来,加深理解。假设我们在构建一个”Todo应用”,包含两个一面,一个待办列表页面,另一个是添加待办事项的页面。我们来一步步实现它。
1、搭建环境
要使用react-router,必须得把react的页面配置起来。我们简单地使用webpack来进行配置,并编写简单的页面,搭建起一个开发环境。目录信息如下:
- package.json
- webpack.config.js
- src
- AddTodo.js (添加待办事项页面)
- app.js (顶层App组件)
- index.js (入口文件)
- Todo.js (待办事项)
- TodoList.js (待办事项列表页面)
具体实现参考 这里 。
2、添加react-router
react-router 4.0+的三类组件(即路由组件、导航组件和路由匹配组件),都在”react-router-dom”这个npm包里面。我们先在项目根目录下安装依赖。
> npm install -D react-router-dom
依赖安装完成之后。我们来实现路由。按照上面提到的react-router工作的三个步骤,我们来一步步实现。
2.1 添加<Router />组件
在app的顶层添加router组件,这里我们的index.js入口文件,就是整个web app的顶部,所以我们在index.js文件中添加<Router />。
import React from 'react'
import ReactDOM from 'react-dom'
import { HashRouter as Router } from 'react-router-dom'
import App from './app'
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementsByTagName('BODY')[0],
)
这里我们使用HashRouter,因为是前端的简单实现,使用HashRouter和BrowserRouter都可。然后把<Router />把 < App />包裹起来,就完成任务了。
但是Router到底做了些什么?为什么要加Router在顶层呢?
2.2 使用<Link />组件定义路由
todo应用的操作逻辑,进来之后首先展现列表页;从列表页,可以进入“添加页面”;而从“添加页面”又可以返回列表页,形成一个闭环。
列表页(TodoList.js)添加 <Link /> 的代码如下:
|
|
添加页(AddTodo.js)添加 <Link /> 的代码如下:
|
|
2.3 使用<Route />组件展现路由对应的UI
上一个小节,我们列表页的路由为”/“,AddTodo页面的路由为”/addTodo”。所以我们在使用<Route />就使用这两个路由定义。<Route />有三种方式渲染路由组件,
- component:component属性,直接配置需要展示的组件即可;
- render: render是一个方法,可以添加函数定义;而要展示的组件,通过return返回即可展示;
- children:children和render有一点类似,都是一个方法,不过children中的组件,无论路由是否匹配都会展示。
PS: 当看到children属性的时候,我们可能会想到在react的组件树,父组件可以通过children组件获取到子组件。没错,这里的children和react中定义的是一样的。
我们在app.js文件中定义<Route />,代码如下(只展示render部分的代码):
|
|
3、结语
以上就是,一个简单的使用了react-router的react SPA应用。详细代码请 戳这里