前端路由
- 路由这个概念最早出现在后端,通过⽤户请求的url导航到具体的html⻚⾯。
- 现在的前端路由不同 于传统路由,它不需要服务器解析,⽽是可以通过hash函数或者history API来实现。
- 在前端开发中,可以使⽤路由设置访问路径,并根据路径与组件的映射关系切换组件的显示
- 这整个过程都是在同 ⼀个⻚⾯中实现的,不涉及⻚⾯间的跳转,这也就是常说的单⻚应⽤(spa)。
1、查看源码姿势
1.1 代码仓库
https://github.com/ReactTraining/react-router
2.2 包说明
- react-router 公共基础包
- react-router-dom 在浏览器中使⽤,依赖react-router
- react-router-native 在react-native中使用,依赖react-router
2.3 源码位置
- react-router 源码位置
react-router/packages/react-router/modules/
- react-router-dom 源码位置
react-router/packages/react-router-dom/modules/
2.4 文件结构
Hooks
暂不关注<Link>
<NavLink>
<Prompt>
暂不关注<Redirect>
<Route>
<Router>
<HashRouter>
<BrowserRouter>
<MemoryRouter>
暂不关注<StaticRouter>
暂不关注
<Switch>
- generatePath
暂不关注 - history
- location
暂不关注 - match
暂不关注 - matchPath
暂不关注 - withRouter
3、React-Router源码分析
3.1 四种 Router 源码对比
<!--HashRouter-->
//便于梳理代码结构,已删除部分代码
import React from "react";
import {
Router } from "react-router";
import {
createHashHistory as createHistory } from "history";
/**
* The public API for a <Router> that uses window.location.hash.
*/
class HashRouter extends React.Component {
history = createHistory(this.props);
render() {
return <Router history={
this.history} children={
this.props.children} />;
}
}
export default HashRouter;
<!--BrowserRouter-->
//便于梳理代码结构,已删除部分代码
import React from "react";
import {
Router } from "react-router";
import {
createBrowserHistory as createHistory } from "history";
/**
* The public API for a <Router> that uses HTML5 history.
*/
class BrowserRouter extends React.Component {
history = createHistory(this.props);
render() {
return <Router history={
this.history} children={
this.props.children} />;
}
}
export default BrowserRouter;
<!--MemoryRouter-->
//便于梳理代码结构,已删除部分代码
import React from "react";
import {
createMemoryHistory as createHistory } from "history";
import Router from "./Router.js";
/**
* The public API for a <Router> that stores location in memory.
*/
class MemoryRouter extends React.Component {
history = createHistory(this.props);
render() {
return <Router history={
this.history} children={
this.props.children} />;
}
}
export default MemoryRouter;
<!--StaticRouter-->
//便于梳理代码结构,已删除部分代码
import React from "react";
import {
createLocation, createPath } from "history";
import Router from "./Router.js";
/**
* The public top-level API for a "static" <Router>, so-called because it
* can't actually change the current location. Instead, it just records
* location changes in a context object. Useful mainly in testing and
* server-rendering scenarios.
*/
class StaticRouter extends React.Component {
render() {
const {
basename = "", context = {
}, location = "/", ...rest } = this.props;
const history = {
createHref: path => addLeadingSlash(basename + createURL(path)),
action: "POP",
location: stripBasename(basename, createLocation(location)),
push: this.handlePush,
replace: this.handleReplace,
go: staticHandler("go"),
goBack: staticHandler("goBack"),
goForward: staticHandler("goForward"),
listen: this