(一)【react-router v6】react-router v6基本用法,带你彻底搞懂前端路由原理、react-router V6带来了什么
React想做一个好的项目,你有3个东西非掌握不可。
- React
- 路由
- 状态管理
课程版本
高情商: 激动人心的版本(标志性产物,数据路由(颠覆了传统模式,性能))
低情商: 不再支持class类组件, 全hooks支持
什么是路由?
- 多页面
- 单页面(react vue)
环境准备
安装node v18.17
推荐使用nvm
https://nvm.uihtm.com/
https://github.com/facebook/create-react-app
https://github.com/remix-run/react-router
安装路由依赖
npm i react-router-dom
代码仓库
https://serverless-100003132201.coding.net/public/react-router-v6/react-router-v6/git/files
react-router和react-router-dom的区别?
withRouter的作用?
import {useLocation,useNavigate,useParams,
} from "react-router-dom";function withRouter(Component) {function ComponentWithRouterProp(props) {let location = useLocation();let navigate = useNavigate();let params = useParams();return (<Component {...props} router={{ location, navigate, params }} />);}return ComponentWithRouterProp;
}
BrowserRouter(99%)
后台做一些配置
问题: browserRouter在使用的时候会遇到404的问题。
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { BrowserRouter, Route, Routes } from 'react-router-dom'const root = ReactDOM.createRoot(document.getElementById('root'));function Bpp () {return (<h1>bpp</h1>)
}root.render(<BrowserRouter basename='pc'><Routes><Route path="/app" element={<App />} /><Route path="/bpp" element={<Bpp />} /></Routes></BrowserRouter>
);
HashRouter
了解即可,非必要不要使用这种方式
缺陷:
- 很丑
- 后期要改造服务端渲染很不方便
MemoryRouter
内存型路由
应用场景: 单测
import * as React from "react";
import { create } from "react-test-renderer";
import {MemoryRouter,Routes,Route,
} from "react-router-dom";describe("My app", () => {it("renders correctly", () => {let renderer = create(<MemoryRouter initialEntries={["/users/mjackson"]}><Routes><Route path="users" element={<Users />}><Route path=":id" element={<UserProfile />} /></Route></Routes></MemoryRouter>);expect(renderer.toJSON()).toMatchSnapshot();});
});
NativeRouter
import * as React from "react";
import { NativeRouter } from "react-router-native";function App() {return (<NativeRouter>{/* The rest of your app goes here */}</NativeRouter>);
}
StaticRouter
静态路由
import * as React from "react";
import * as ReactDOMServer from "react-dom/server";
import { StaticRouter } from "react-router-dom/server";
import http from "http";function requestHandler(req, res) {let html = ReactDOMServer.renderToString(<StaticRouter location={req.url}>{/* The rest of your app goes here */} </StaticRouter>);res.write(html);res.end();
}http.createServer(requestHandler).listen(3000);
Outlet
子页面的占位符。
我们要实现通用的header,就是用这个玩意。
useNavigate
页面跳转
import { Outlet, useNavigate } from "react-router-dom"function Layout () {const navigate = useNavigate()console.log('navigate',navigate )return (<div><h1>我是通用的头部</h1><button onClick={() => navigate('/app')}>跳转到App</button><button onClick={() => navigate('/bpp')}>跳转到bpp</button><Outlet /></div>)
}export default Layout
useLocation
可以获取一些navigate路由过来的状态
import { Outlet, useNavigate } from "react-router-dom"function Layout () {const navigate = useNavigate()console.log('navigate',navigate )return (<div><h1>我是通用的头部</h1><button onClick={() => navigate('/app')}>跳转到App</button><button onClick={() => navigate('/bpp', {state: {user_id: 'james',from: 'layout'}})}>跳转到bpp</button><Outlet /></div>)
}export default Layout
动态路由
useParams
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { HashRouter, BrowserRouter, Route, Routes, useLocation, useParams } from 'react-router-dom';
import Layout from './layout';const root = ReactDOM.createRoot(document.getElementById('root'));function Bpp() {const location = useLocation()console.log('location bpp',location)return (<h1>bpp</h1>)
}// baidu.com/user/1231242989899function User () {const params = useParams()console.log('params',params)return (<h1>{params.id}</h1>)
}root.render(<BrowserRouter><Routes><Route path='/' element={<Layout />}><Route path="/app" element={<App />} /><Route path='/bpp' element={<Bpp />} /><Route path='/user/:id/:name' element={<User />} /></Route></Routes></BrowserRouter>);