本篇文章参考极客时间 React Router 教程
文章目录
前言
最近在研究 React 的相关技术栈,隐隐约约有种感觉,现在的框架发展路线不再是只提供框架,而是一种概念,一种生态,就像你用苹果手机,你使用的不仅仅是苹果的手机产品,它的背后有一套完整的解决方案在支持。首先你必须注册苹果账号才能下载 app ,其次所有软件又都是 IOS 提供的。
再举个例子,学会 react ,相当于造出了 V12 的引擎,如果没有配套生态的使用,那就是在用这台引擎耕地。
所以只会使用 React 的时候,并不能把其中的精髓发挥到极致,唯一办法就是,接受它的全部。
为什么使用React Router
因为配置路由一般是小组长的工作,想要升值加薪,升为组长,就必须要会。
当然,路由是提升用户体验的重要一环,当需要页面切换而又不想重新加载新页面的时候,就需要用到路由。同时还可以增强组织资源的语义,每个页面的业务功能都是高内聚,低耦合的,通过 url 就可以将页面进行很好的隔离。
基于路由配置进行资源组织的好处
- 实现业务逻辑的松耦合,
- 易于扩展,重构和维护
- 路由层面实现 Lacy Load
一、路由定义
1.1 路由实现基本架构
React Router 是在一个组件容器中,根据 url 来判断当前应该显示什么样的组件。
对应代码如下:
const Home = () => <h1>Home</h1>;
const Hello = () => <h1>Hello</h1>;
const About = () => <h1>About</h1>;
...
<Router>
<div id="menu">
<ul>
<li><Link to="/home">Home</Link></li>
<li><Link to="/hello">Hello</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
<div id="page_container">
<Route patch="/home" component={Home} />
<Route patch="/hello" component={Hello} />
<Route patch="/about" component={About} />
</div>
</div>
</Router>
上面 Link 标签是 React Router 给我们提供的,当点击这个 Link 的时候,url 会发生变化,但是页面不会刷新,只是显示对应的组件。这一点带来的好处就是,当我们在浏览网页的时候,点击刷新后,我们还是在刚才浏览的页面,而不是被迫跳转回首页。
这个 Link 虽然 render 出来是一个连接的标志,但是点击的时候,并不会真的告诉浏览器,而是通过 React Router 来控制页面变化。
1.2 React Router 特性
路由的概念是后端最先拥有的,其实就是 url 的对照表,类似书籍的目录。选择那个目录,对应到哪个页面。后端路由一般通过路由的配置表来定义,比如说 express 等。
React Router 作为前端路由,有一些自己的特性。
1.2.1 声明式路由定义
通过标签定义,可以在任何地方使用。
const app = () => {
<div>
<nav>
<Link to="/home">Home</Link>
</nav>
<div>
<Route patch="/home" component={Home} />
</div>
</div>
}
1.2.2 动态路由
传统服务端路由一旦定义好了,就是一个配置文件,是静态的放在那里,但是对于 React Router 来说它是动态路由,因为只有当页面 render 的时候,路由才会被解析。
二、路由实现的三种方式
React Router 提供了三种路由的实现方式。
- URL 路径
- hash 路由
- 内存路由
大部分的时候可以通过 URL 路径实现 ,但是有些低版本浏览器不支持 url 改变后,页面不刷新,这个时候就需要用到 hash 路由 。三种路由的使用方法基本一致,只有导入的时候名字不同而已,具体区别如下:
2.1 URL 路径
这种方式是通过改变 URL 来进行页面内容的改变,所以点击不同的 Link 的时候,url地址会根据 Link 的设置而变化。
import React, { Component } from 'react';
//url路径的导入名称是 BrowserRouter
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom';
const Home = () => <h1>Home</h1>;
const Hello = () => <h1>Hello</h1>;
const About = () => <h1>About</h1>;
class Test extends Component {
render() {
return (
<Router>
<div id="menu">
<ul>
<li><Link to="/home">Home</Link></li>
<li><Link to="/hello">Hello</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
<div id="page_container">
<Route patch="/home" component={Home} />
<Route patch="/hello" component={Hello} />
<Route patch="/about" component={About} />
</div>
</div>
</Router>
);
}
}
export default Test;
浏览器显示情况如下,(当点击 About 的时候)
2.2 hash 路由
这种方式为了适配部分浏览器,不允许 URL 改变的时候,页面不刷新。使用方法与上面一样,只是导入名称不同。
import React, { Component } from 'react';
// hash 路由的导入名称是 HashRouter
import {
HashRouter as Router,
Route,
Link
} from 'react-router-dom';
...
浏览器地址部分也会有所变化,会有一个 # 在路由地址前。
2.3 内存路由
内存路由不是通过页面地址进行存储的,而是存在内存当中,进行保存。
import React, { Component } from 'react';
import { Route, Link } from 'react-router-dom';
// 内存路由的导入名称是 MemoryRouter 并且是通过 react-router 导入的
import { MemoryRouter as Router } from 'react-router';
...
点击不同 Link 的时候,URL 地址不变。
三、核心 API
- <Link> 普通连接,不会触发浏览器刷新。
- <NavLink> 类似 Link 但是会添加当前选中状态。
- <Prompt> 满足条件时提示用户是否离开当前页面。
- <Redirect> 重定向当前页面,例如登录判断。
- <Route> 路由配置的核心标记,路由匹配时显示对应组件(此组件不排他,只要路由匹配,组件都会显示)
- <Switch> 只显示第一个匹配的路由。