install
npm install --save react-router
--save
- used to add dependencies to package.json
- auto install when others clone your project
import module
- use es6 moudule grammer
import {Router, Route, Link} from 'react-router-dom@6'
create react app use vite
- use vite to create a react project
npm create vite@latest - cd project root
npm installnpm run dev
router authentication practice
the benefits of router component encapsulation
- easy to manage, many components use the same router component
project content structure
router
- -router.tsx //register router component
- -routerMap.tsx // router map
- -privateRouter.ts // authentic router component
- -router.ts //
write root router component
import React from 'react'
import ReactDom from 'react-dom'
import App from './App.tsx'
import {BrowserRouter} from 'react-router-dom'
ReactDom.createRoot(document.getElementById('#root')).render(
<React.strictMode>
<BrowserRouter>
<App/>
</BrowserRouter>
</React.strictMode>
)
React.createRoot(dom)
- the new API of react18
- create root render
! in ts
document.getElementById('#root') !- ! means not null or undefined
the principal of privateRouter component
- get token
- if token expired or null, redirect to login page
- else render children componet
- basic code
import { useEffect } from "react"
const privateRouter = (children) => {
function isExpiredToken(){
}
try {
const token = getToekn()
useEffect(() => {
if (!token || isExpiredToken()) {
navigator('/login')
}
}, [])
} catch {
}
return <>{children}</>
}
export default privateRouter
the structure of routerMap js file
- export an array object named routerMap
- routerMap is object array
- each object contains
path:'/path', element: <name> - or
childrenobject array, each object contaispath elementtoo path:'*'means all path
export const routerMap = [
{
path: "/login",
element: <Login />,
},
{
path: "/",
element: (
<PrivateRoute>
<Layout />
</PrivateRoute>
),
children: [
{
path: "/user",
element: <User />,
},
],
},
{
path: "*",
element: <Navigate to="/login" />,
}, //其他没有被注册过的路径统一重定位到login
];
register routerMap to router component
- map url to component
import {useRouters} from 'react-router-dom'
import {router} from './routerMap'
const Router = ()=>{
const routerMap = useRouters(router)
return <div>{routerMap}</div>
}
export default Router
basic knowledge
createBroswerRouter
- create the relationship between path and element
- element can be
- grammar
const router = createBroswerRouter([path:'/',element:<h1>123</h1>])
apply router to app
<RouterProvider router = {router}/>
broswerRouter or hashRouter
- hashRouter adapt to low version broswer
- broswer router is more powerful
deploy @ path name
- open vite.config.js
import {join} from 'node:path'
//join 路径拼接
resolve: {
alias: {
'@':join(__dirname, './src')
}
}
- open
tsconfig.json
complierOptions: {
baseUrl: '.',
"path":{
'@/*':{
"./src/*"
}
}
}
- open
main.tsx
import Root from '@/index.js'
- the benefit of @ no matter which file , @ alwasy replace the same path
error path page
createBroswerRouter([path:'./',element:<root/>, errorElement:<errorElement>])
useRouterError
const error = useRouterError() as errorResopnseerror.message or error.statusText
children route path
- add children route to father route
- children path can start with /
const route = createBroswerRouter([{
path:'/',element:<root/>,children:[{path:'children/:id', element:<children/>]
}])
- add
<outlet>to father component
import {Outlet} from 'react-router-dom'
<Outlet/>
use link to replace a
<a>will reflash when switch route<link>will not reflash<link to = 'path'/>
loader
- add loader function to component
export default const loader = ()=>{
return null
}
- import loader from component
import {loader} from './root'
- add loader attribute to object
loader: loader
- after match router, before show component, will run loader function
useLoaderData
import {useLoaderData} from 'react-router-dom'
const data = useRouterData()
...
loader(){
return {name:'keke',age:'12'}
}