reactRouter实现原理
阅读此文档需掌握一下知识点:
- React Hooks
- History API
index.js
import { BrowserRouter, Route, RouterContext } from './router'
function Home() {
return <h2>Home</h2>
}
function About() {
return <h2>About</h2>
}
function Users() {
return <h2>Users</h2>
}
function App() {
return (
<BrowserRouter>
<RouterContext.Consumer>
{() => (
<>
<button onclick={()=>{ router.goPath('/')}}>home</button>
<button onclick={()=>{ router.goPath('/about')}}>about</button>
<button onclick={()=>{ router.goPath('/users')}}>users</button>
<Route path="/" component={<Home />} />
<Route path="/about" component={<About />} />
<Route path="/users" component={<Users />} />
</>
)}
</RouterContext.Consumer>
</BrowserRouter>
)
}
export default App
router.js
import React,{ useState, useEffect } from 'react'
export const RouterContext = React.createContext()
// BrowserRouter组件
export function BrowserRouter(props) {
// 初始化数据
const [path, setPath] = useState(window.location.pathname || '/')
useEffect(() => {
// 监听浏览器路由前进后退事件
window.addEventListener('popstate', handlePopstate)
// 卸载监听
return () => {
window.removeEventListener('popstate', handlePopstate)
}
})
function handlePopstate() {
const { pathname } = window.location
setPath(pathname)
}
// 跳转方法
function goPath(path) {
window.history.pushState({}, '', path)
setPath(path)
}
// 封装路由数据给Provider使用
const routerData = {
path
goPath,
}
return (
<RouterContext.Provider value={routerData}>
{props.children}
</RouterContext.Provider>
)
}
// Route 组件
export function Route(props) {
return (
<RouterContext.Consumer>
{({path, setPath}) => {
if (props.path === path) {
return props.component
}
return null
}}
</RouterContext.Consumer>
)
}
export {
BrowserRouter,
Route,
RouterContext
}