基于 React Router6。
React Router 是 React 的一个插件库,是完整的 React 路由解决方案。不是 Facebook 开发的。
目前前端流行的三个框架,都有自己的路由实现:
- React 的 React Router。
- Vue 的 Vue Router。
Vue 全家桶全部是由官方所维护的。
- Angular 的 ngRouter。
安装:
React Router 包含 3 个库: react-router
、react-router-dom
和 react-router-native
。
react-router
:提供核心的路由组件与函数。react-router-dom
:提供浏览器运行环境所需的特定组件。react-router-native
:提供react-native
运行环境所需的特定组件。
实际使用中,不会直接安装 react-router
,而是根据应用运行的环境选择安装 react-router-dom
或 react-router-native
。由于 react-router-dom
和 react-router-native
都依赖 react-router
,所以在安装时, react-router
也会自动安装。
Web 开发只需要通过 npm install react-router-dom
安装 react-router-dom
;然后在项目中使用 import { BrowserRouter, Route, Link } from 'react-router-dom'
引入即可使用。
使用:
// index.js
import ReactDOM from 'react-dom/client'
// 1. 从 react-router-dom 中引入 HashRouter
import {HashRouter} from 'react-router-dom'
import App from './App'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
// 2. 包裹根组件,给整个应用开启路由功能,就能监听路径的改变,并且将相应的路径传递给子组件
<HashRouter>
<App />
</HashRouter>
)
// App.jsx
import React, {PureComponent} from 'react'
// 1. 从 react-router-dom 中引入 Routes、 Route、 Link 和 Navigate
import {Routes, Route, Link, Navigate} from 'react-router-dom'
import Home from './components/Home'
import About from './components/About'
import NotFound from './components/NotFound'
class App extends PureComponent {
render() {
return (
<div>
<div>
{/* 2. 点击跳转到指定的路径 */}
<Link to='/home'>首页</Link>
<Link to='/about'>关于</Link>
</div>
{/* 3. 使用 Routes 包裹所有的 Route */}
<Routes>
{/* 4. 使用 Route 配置路径和组件的映射关系。匹配到路径后渲染对应的组件。 */}
{/* 一加载进来是根路径时,使用 Navigate 自动跳转到 /home 路径 */}
<Route path='/' element={<Navigate to='/home' />} />
<Route path='/home' element={<Home/>} />
<Route path='/about' element={<About/>} />
{/* 如果上面的路由都没有匹配到,则显示 NotFound 页面。* 表示匹配所有 */}
<Route path='*' element={<NotFound/>} />
</Routes>
</div>
)
}
}
export default App
React Router 中的组件:
React Router 最主要的 API 是提供了一些组件。
<BrowserRouter>
和 <HashRouter>
:
<BrowserRouter>
和 <HashRouter>
:监听路径的改变,并且将相应的路径传递给子组件。<BrowserRouter>
是使用 history 模式,<HashRouter>
是使用 hash 模式。
import ReactDOM from 'react-dom/client'
// 1. 从 react-router-dom 中引入 HashRouter
import {HashRouter} from 'react-router-dom'
import App from './App'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
// 2. 包裹根组件,给整个应用开启路由功能,就能监听路径的改变,并且将相应的路径传递给子组件
<HashRouter>
<App />
</HashRouter>
)
<Routes>
和 <Route>
:
<Routes>
:
<Routes>
:用来包裹所有的 <Route>
,匹配其中的一个路由。
React Router V5 中使用的是
<Swithc>
。
<Route>
:
<Route>
:用来配置路径和组件的映射关系。路由最核心的就是路径和组件的映射关系,一个 path 对应一个 component,当 path 和当前地址栏的 URL 路径匹配时,去渲染对应的 element。
React Router V5 中
<Route>
可以单独存在,也可以放到<Switch>
中。
但是 React Router V6 中<Route>
只能放到<Routes>
中。
属性:
- path:用于设置匹配的路径。
React Router V5 中支持设置 exact 属性,用于设置精准匹配,只有精确匹配到完全一致的路径,才会渲染对应的组件。
React Router V6 中不再支持设置 exact 属性,默认就是精准匹配。 - element:用于设置匹配到路径后,要渲染的组件。
React Router V5 中使用的是 component 属性。
import React, {PureComponent} from 'react'
// 1. 从 react-router-dom 中引入 Routes 和 Route
import {Routes, Route} from 'react-router-dom'
import Home from './components/Home'
import About from './components/About'
class App extends PureComponent {
render() {
return (
<div>
{/* 2. 使用 Routes 包裹所有的 Route */}
<Routes>
{/* 3. 使用 Route 配置路径和组件的映射关系,匹配到路径后渲染对应的组件。 */}
<Route path='/home' element={<Home/>} />
<Route path='/about' element={<About/>} />
</Routes>
</div>
)
}
}
export default App
<Link>
和 <NavLink>
:
<Link>
:
<Link>
:用于设置路径的跳转,最终会被渲染成 <a>
元素。
属性:
- to:用于设置要跳转到的路径。
import React, {PureComponent} from 'react'
// 1. 从 react-router-dom 中引入 Link
import {Link} from 'react-router-dom'
import Home from './components/Home'
import About from './components/About'
class App extends PureComponent {
render() {
return (
<div>
{/* 2. 点击跳转到指定的路径 */}
<Link to='/home'>首页</Link>
<Link to='/about'>关于</Link>
</div>
)
}
}
export default App
<NavLink>
:
<NavLink>
:用于设置路径的跳转,最终会被渲染成 <a>
元素。<NavLink>
是在 <Link>
的基础上增加了一些样式属性,被选中时会自动添加上 class='active'
,开发者可以任意编写 .active
来给选中态设置样式。
属性:
-
to:用于设置要跳转到的路径。
-
className:用于设置 class。属性值为字符串或者函数。
// className 属性值为一个字符串时,会和被选中时默认添加的 active 合并 <duv> <NavLink to='/home' className='home-link'>首页</NavLink> <NavLink to='/about' className='about-link'>关于</NavLink> </duv>
// className 属性值为一个函数时,函数的参数是一个对象,包含 isActive 属性表示是否被选中。会覆盖被选中时默认添加的 active <duv> <NavLink to='/home' className={({isActive}) => isActive ? 'active-link' : 'inactive-link'}>首页</NavLink> <NavLink to='/about' className={({isActive}) => isActive ? 'active-link' : 'inactive-link'}>关于</NavLink> </duv>
-
style:用于设置 style。属性值为对象或者函数。
<div> // style 属性值为一个函数时,参数是一个对象,包含 isActive 属性表示是否被选中。 <NavLink to='/home' style={({isActive}) => ({color: `${isActive ? 'red' : 'black'}`})}>首页</NavLink> <NavLink to='/about' style={({isActive}) => ({color: `${isActive ? 'red' : 'black'}`})}>关于</NavLink> </div>
<Navigate>
:
<Navigate>
:用于路由的重定向。只要这个组件一显示,就会自动跳转到 to 属性指定的路径中。
React Router V5 中是
<Redirect>
。
import React, {PureComponent} from 'react'
import {Navigate} from 'react-router-dom'
class Login extends PureComponent {
state = {
isLogin: false,
}
login = () => {
this.setState({isLogin: true})
}
render() {
return (
<div>
{/* 默认显示登录按钮。只要一点击登录按钮登录后,就立马跳转到 Home 页面 */}
{this.state.isLogin ? <Navigate to='/home' /> : <button onClick={this.login}>登录</button>}
</div>
)
}
}
export default Login
React Router 中的钩子函数:
React Router 还提供了一些钩子函数,下一节会详述这些钩子函数的用法。
- useNavigate:用于在函数组件中进行手动跳转。
- useParams:用于在函数组件中获取动态路由的参数。
- useSearchParams:用于在函数组件中获取路径中的 search 参数。
- useLocation:用于在函数组件中获取 location。
- useRoutes:用于在函数组件中通过配置的方式使用路由。