ReactRouter6.0 安装使用
官网
官方英文文档:Feature Overview v6.10.0 | React Router
中文文档:www.reactrouter.cn/docs/gettin…
安装
# npm 安装
npm install react-router-dom
# yarn 安装
yarn add react-router-dom
# pnpm 安装
pnpm add react-router-dom
路由组件
BrowserRouter
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
// 使用组件包裹
<BrowserRouter>
<App />
</BrowserRouter>
Routes定义路由
<Routes>
<Route path='/' element={<App />}></Route>
<Route path='/demo' element={<React />}></Route>
</Routes>
组件定义
function React() {
return <h2>欢迎学习React课程</h2>
}
路由跳转
官网
官方英文文档:Feature Overview v6.10.0 | React Router
中文文档:www.reactrouter.cn/docs/gettin…
使用
NavLink
<NavLink to="/react"></NavLink>
Link
<Link to="/react"></Link>
Navigate(重定向组件)
// 路由中使用
<Route path='/vite' element={<Navigate to={'/react'} />}></Route>
// 组件中使用
function Vue() {
return <h2>欢迎学习Vue课程{<Navigate to={'/react'} />}</h2>
}
Hook - useNavigate
// 前提:必须在函数组件里面定义
const navigate = useNavigate();
// 点击按钮,进行跳转
navigate('/react')
404定义
<Route path='*' element={<NotFound />}></Route>
API创建路由(推荐方式)
useRoutes
function Router(){
let element = useRoutes([
{
path: "/",
element: <App />,
},
{
path: "/vite",
element: <Vite />,
},
{
path: "/react",
element: <ReactDemo />
},
{
path: "*",
element: <NotFound />
},
]);
}
export default Router;
// 在main.tsx中加载
import BaseRouter from './router2'
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<BrowserRouter>
<BaseRouter />
</BrowserRouter>
)
createBrowserRouter
import { createBrowserRouter, RouterProvider} from "react-router-dom";
// 创建路由
const router = createBrowserRouter([
{
path: "/",
element: <App />,
},
{
path: "/vite",
element: <Vite />,
},
{
path: "/react",
element: <ReactDemo />
},
{
path: "*",
element: <NotFound />
},
]);
// 传递给RouterProvider
<RouterProvider router={router} />
createHashRouter
用法同上。
动态路由、嵌套路由
basename
基础路由地址
{
basename: '/app'
}
动态路由
{
path: '/order/:orderId',
element: <Order/>
}
{
path: '/goods/:goodsId/order/:orderId',
element: <Order/>
}
function Order(){
const params = useParams();
return <div>
<h2>商品组件</h2>
<p>
<span>商品ID:{params.goodsId}</span>
<span>订单ID:{params.orderId}</span>
</p>
</div>
}
嵌套路由
{
path: '/goods',
element: <Goods />,
children: [
{
path: 'list',
element: (
<div>
<p>商品一</p>
<p>商品二</p>
</div>
)
},
{
path: 'cart',
element: (
<div>
<p>苹果手机,价格5999</p>
<p>小米手机,价格2999</p>
</div>
)
}
]
}
// 组件定义
function Goods() {
return (
<div>
<h2>商品主页</h2>
<Outlet />
</div>
)
}
两个知识点
-
useParams()
-
Outlet(相当于Vue里面的 组件)
5-6 Data API
前置条件
只有上面四个API创建的路由才有Data API功能
Loader、useLoaderData
数据加载器
{
path: '/order/:id',
element: <Order />,
loader: orderLoader
}
function orderLoader({ params }: any) {
return params.id;
}
function orderLoader({ params }: any) {
if (!sessionStorage.token) return redirect('/login')
return {
token: sessionStorage.token
}
}
function orderLoader({ params }: any) {
if (!sessionStorage.token) return redirect('/login')
return fetch(`/${params.id}.json`)
}
Action、useActionData
5-8 总结
前面七节课详细讲解了ReactRouter6.0的基础语法,我们在实战部分会深入使用。每节课的课程案例都创建对应的分支,大家可以克隆源码,切换分支查看。
路由安装
# npm 安装
npm install react-router-dom
# yarn 安装
yarn add react-router-dom
# pnpm 安装
pnpm add react-router-dom
路由组件
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
// 使用组件包裹
<BrowserRouter>
<Routes>
<Route path='/' element={<App />}></Route>
<Route path='/demo' element={<React />}></Route>
</Routes>
</BrowserRouter>
注意,可以使用Hook简写
function Router(){
let element = useRoutes([
{
path: "/",
element: <App />,
},
{
path: "/demo",
element: <React />,
}
]);
}
export default Router;
// 在main.tsx中加载
import Router from './router'
<BrowserRouter>
<Router />
</BrowserRouter>
通过API创建路由
import { createBrowserRouter, RouterProvider} from "react-router-dom";
// 创建路由
const router = createBrowserRouter([
{
path: "/",
element: <App />,
},
{
path: "/demo",
element: <React />,
}]);
// 传递给RouterProvider
<RouterProvider router={router} />
动态路由
{
path: '/order/:orderId',
element: <Order/>
}
{
path: '/goods/:goodsId/order/:orderId',
element: <Order/>
}
function Order(){
const params = useParams();
return <div>
<h2>商品组件</h2>
<p>
<span>商品ID:{params.goodsId}</span>
<span>订单ID:{params.orderId}</span>
</p>
</div>
}
嵌套路由
{
path: '/goods',
element: <Goods />,
children: [
{
path: 'list',
element: (
<div>
<p>商品一</p>
<p>商品二</p>
</div>
)
}
]
}
// 组件定义
function Goods() {
return (
<div>
<h2>商品主页</h2>
<Outlet />
</div>
)
}
Data API
只有API创建的路由才有,组件创建的路由没有Data API
Loader拦截
{
path: '/order/:id',
element: <Order />,
loader: orderLoader
}
function orderLoader({ params }: any) {
return params.id;
}
Action提交
// 路由定义,定义action
{
path: '/login',
element: <Login />,
action: loginAction
}
// 表单组件定义,提交以后,会触发action
function Login() {
const errors: any = useActionData()
return (
<Form method='post'>
<p>
<input type='text' name='email' />
{errors?.email && <span>{errors.email}</span>}
</p>
<p>
<input type='text' name='password' />
{errors?.password && <span>{errors.password}</span>}
</p>
<p>
<button type='submit'>登录</button>
</p>
</Form>
)
}
async function loginAction({ request }: any) {
const formData = await request.formData()
const email = formData.get('email')
const password = formData.get('password')
// TODO
console.log('创建用户成功')
return redirect('/')
}