1. react-router 与react-router-dom
react-routerReact Router 核心react-router-dom用于 DOM 绑定的 React Routerreact-router-native用于 React Native 的 React Router
2. 页面跳转传参数
- 方法一:url params - 形如/myurl/:id
this.props.history.push(`/myurl/${id}`);
const { id } = this.props.match.params
- 方法二:query params - 形如 /myurl?id=1
const { search } = this.props.location;
const prevParams = qs.parse(search.replace(/^\?/, ''));
const params = { id: 1, name: 'chris' };
this.props.history.push({ pathname: '/myurl',
search: qs.stringify({ ...prevParams, ...params })});
- 方法三:url with state
this.props.history.push({ pathname: '/myurl', state: { num: 1 }});
const { state = {} } = this.props.location;
3. react-router-dom 相关hooks
import React from 'react';
import { useParams, useLocation, useHistory } from 'react-router-dom';
import qs from 'qs';
function MyUrl () {
// 跳转url
const history = useHistory(); // hook: useHistory
function changeUrl () {
history.push({
pathname: '/myurl/2',
search: 'name=chris',
state: { fromSource: 1 },
})
}
// 获取match params
const params = useParams(); // hook: useParams
const { id } = params;
// 获取location params
const location = useLocation(); // hook: useLocation
const { search, state = {} } = location;
// 获取location.search中的参数
const { name } = qs.parse(search.replace(/^\?/, ''));
// 获取location.state中的参数
const { fromSource } = state;
return (
<div>
<div>
myurl id: { id },<br/>
search name: { name },<br />
state fromSource: { fromSource },<br />
</div>
<div onClick={ changeUrl }>
change url
</div>
</div>
)
}
export default MyUrl;
// 路由
const route = {
path: '/myurl/:id',
component: myUrl,
};
<Route path={route.path} component={route.component} />
3原理
BrowserRouter
import {createContext} from 'react';
const HistoryContext = createContext();
function BrowserRouter(props) {
const [path, setPath] = useState(() => {
// 首次渲染,获取到对应的路由
const {pathname} = window.location;
return pathname || '/';
});
...
// 点击ui跳转页面
const push = function(path) {
setPath(path);
window.history.pushState({path}, null, path);
}
const goBack = function() {
window.history.go(-1);
}
return (
<RouterContext.Provider value={path}>
<HistoryContext.Provider value={{
push,
goBack
}}>
{props.children}
</HistoryContext.Provider>
</RouterContext.Provider>
);
}
HashRouter
import {useEffect, useState} from 'react';
import RouterContext from './routerContext';
import HistoryContext from './historyContext';
// 自定义HashRouter
function HashRouter(props) {
const [path, setPath] = useState(() => {
const {hash} = window.location;
if(hash) {
return hash.slice(1);
}
return '/#/';
});
useEffect(function componentDidMount() {
// 监听用户点击浏览器的前进,后退按钮跳转页面
window.addEventListener('hashchange', handlePopstate);
return function componentWillUnmount() {
window.removeEventListener('hashchange', handlePopstate);
}
}, []);
const handlePopstate = function(event) {
const {hash} = window.location;
setPath(hash.slice(1));
}
//history Api: https://developer.mozilla.org/zh-CN/docs/Web/API/History_API
// 点击ui跳转页面
const push = function(path) {
window.location.hash = path;
}
const goBack = function() {
window.history.go(-1);
}
return (
<RouterContext.Provider value={path}>
<HistoryContext.Provider value={{
push,
goBack
}}>
{props.children}
</HistoryContext.Provider>
</RouterContext.Provider>
);
}
export default HashRouter;
参考文章:
欢迎关注我的前端自检清单,我和你一起成长