目前常见的路由分为两种,HashRouter
和BrowserRouter
html
hash
路由的方式主要是经过改变hash
值来改变url
,由于只是改变hash
,因此并不会触发页面刷新,很适合用在单页应用局部更新,window
提供监听hashChange
方法来监听hash值的改变去更新咱们的单页react
window.addEventListener('hashchange', function(e) {
console.log('hashchange', e)
// 更新页面
})
复制代码
history是h5新出的api,让咱们能够在改变url而不刷新页面,主要的几个api是:git
History.back()
: 返回浏览器会话历史中的上一页,跟浏览器的回退按钮功能相同github
History.forward()
:指向浏览器会话历史中的下一页,跟浏览器的前进按钮相同。api
History.go()
: 能够跳转到浏览器会话历史中的指定的某一个记录页。浏览器
History.pushState()
:pushState能够将给定的数据压入到浏览器会话历史栈中,该方法接收3个参数,对象,title和一串url。pushState后会改变当前页面url,可是不会伴随着刷新。bash
History.replaceState()
:replaceState将当前的会话页面的url替换成指定的数据,replaceState后也会改变当前页面的url,可是也不会刷新页面。ide
以上只是实现改变url
不刷新页面,咱们还须要监听用户前进后退的变化。popstate
是history的一个监听事件,能够监听history的变化学习
好了,基本上就是这个原理ui
实现部分主要是利用react
的context api
来存储路由信息,子组件根据context
值去渲染,代码是由hook
实现,不了解的,看以前,学习一下React Hook,下面咱们来实现一下BrowserRouter
import React, { useState } from "react";
let set; // 保存setUrl,由于监听事件我们值加入一次,因此放外面
function popstate(e) {
set(window.location.pathname);
}
// 建立context
export const RouterContext = React.createContext(window.location.pathname);
export default function({ children }) {
const [url, setUrl] = useState(window.location.pathname);
set = setUrl;
window.addEventListener("popstate", popstate);
const router = {
history: {
push: function(url, state, title) {
window.history.pushState(state, title, url);
setUrl(url);
},
replace: function(url, state, title) {
window.history.replaceState(state, title, url);
setUrl(url);
},
// 下面也须要嵌入setUrl,暂不处理
go: window.history.go,
goBack: window.history.back,
goForward: window.history.forward,
length: window.history.length
},
url: url
};
return (
<RouterContext.Provider value={router}>{children}</RouterContext.Provider>
);
}
复制代码
import React, { useContext } from "react";
import { RouterContext } from "./BrowserRouter";
function Route({ component, path }) {
// 获取context
const { history, url } = useContext(RouterContext);
const match = {
path,
url
};
const Component = component;
return url === path && <Component history={history} match={match} />;
}
export default Route;
复制代码
import React, { useContext } from "react";
import { RouterContext } from "./BrowserRouter";
import styled from "styled-components";
const A = styled.a`
text-decoration: none;
padding: 5px;
`;
function Link({ children, to }) {
const { history } = useContext(RouterContext);
const onClick = e => {
e.preventDefault();
history.push(to);
};
return (
<A href={to} onClick={onClick}>
{children}
</A>
);
}
export default Link;
复制代码
查看Github源码 其实很简单的一个东西,了解原理很容易实现,看了这篇文章,你也能够试着去实现一下HashRouter
.