当前位置: 首页 > news >正文

react 路由 react-router-dom

补充一个:类组件,无法使用 useNavigate 这个hook函数,所以,编写一个高阶组件

import { useLocation, useNavigate, useParams, useSearchParams } from 'react-router-dom'// 类组件,无法使用 useNavigate 这个hook函数,
// 所以,编写一个高阶组件,
function withRouter(WrapperComponent) {// 返回一个函数式组件return function (props) {// 1、导航的跳转const navigate = useNavigate()// 2、动态路由的参数,如:/detail/:idconst params = useParams()// 3、查询字符串参数,如:/user?name=why&age=18// location、query 是两种方式const location = useLocation()console.log('location=', location)const [searchParams, setSearchParams] = useSearchParams()const query = Object.fromEntries(searchParams)console.log('query=', query)const router = { navigate, params, query }// props原样传回去return <WrapperComponent {...props} router={router}></WrapperComponent>}
}export default withRouter

使用这个 withRouter

import React, { PureComponent } from 'react'// Link:用于声明式导航(类似 <a> 标签,但不会触发页面刷新)
// OutLet:子路由的占位符,<Outlet /> 是子路由组件的渲染位置,根据当前 URL 路径,自动匹配对应的子路由组件并渲染到此处。
// useNavigate:Hook,用于编程式导航(只能在函数组件中使用)
import { Link, Outlet, useNavigate } from 'react-router-dom'import { withRouter } from '../hoc'export class Home extends PureComponent {navigateTo(path) {const { navigate } = this.props.routernavigate(path)}render() {return (<div><h1>HomePage</h1><div className="home-nav"><Link to="/home/recommend">推荐</Link><Link to="/home/ranking">排名</Link><button onClick={e => this.navigateTo('/home/songmenu')}>歌单</button></div>` 有了占位符,才能显示子路由在哪个位置渲染,没有占位符,子路由根本就不会渲染到页面上。`<Outlet /></div>)}
}// export default Home
export default withRouter(Home)



补充一个

  • 动态路由参数
定义:{ path: '/detail/:id', element: <Detail /> }使用:在 Detail 组件中通过 useParams() 获取参数:import { useParams } from 'react-router-dom'function Detail() {const { id } = useParams() // id = 路径中的动态值(如 "123")return <div>Detail ID: {id}</div>}
  • 查询参数
定义:<Link to="/user?name=why&age=18">用户</Link>使用:在 User 组件中通过 useSearchParams() 获取:import { useSearchParams } from 'react-router-dom'function User() {const [searchParams] = useSearchParams()const name = searchParams.get('name') // "why"const age = searchParams.get('age')   // "18"return <div>User: {name}, Age: {age}</div>}



安装及引入配置:npm i react-router-dom

src/index.js

// 导入 React 核心库和 Suspense 组件(用于代码分割和懒加载)
import React, { Suspense } from 'react'
// 导入 ReactDOM 的客户端渲染方法(React 18+ 新 API)
import ReactDOM from 'react-dom/client'
// 导入根组件 App
import App from './App'`1、安装路由:npm i react-router-dom`
`2、使用 HashRouter 的路由模式`
import { HashRouter } from 'react-router-dom'// 创建根渲染节点,绑定到 HTML 中 id="root" 的 DOM 元素
const root = ReactDOM.createRoot(document.getElementById('root'))root.render(// <React.StrictMode>//   {/*//     3、HashRouter 包裹 <App />//     4、配置 Routes,就是映射关系:path -> component//   */}//   <HashRouter>//     <App />//   </HashRouter>// </React.StrictMode>// <HashRouter>//   <App />// </HashRouter>` 打包的时候,如果要对 About、Login 分别单独打包处理* Suspense 的作用;* 配合 React.lazy 实现组件懒加载,如:const About = React.lazy(() => import('../pages/About'))* 当子组件尚未加载完成时,显示 fallback 的加载状态(此处是 <h3>Loading...</h3>)* 打包工具(如:Webpack)会为动态导入的组件生成单独 chunk。`<HashRouter><Suspense fallback={<h3>Loading...</h3>}><App /></Suspense></HashRouter>
)

如果是类组件

App.jsx

import React, { PureComponent } from 'react'// 配置映射关系
import { Routes, Route, Link, NavLink, Navigate } from 'react-router-dom'import Home from './pages/Home'
import About from './pages/About'
import Login from './pages/Login'
import NotFound from './pages/NotFound'
import Category from './pages/Category'
import Order from './pages/Order'import HomeRecommend from './pages/HomeRecommend'
import HomeRanking from './pages/HomeRanking'export class App extends PureComponent {render() {return (<div className="app"><div className="header"><span>header</span><div className="nav">`NavLink标签,会带一个“active”的class,可以通过这个class编写样式`<NavLink to="/home">首页</NavLink><NavLink to="/about">关于</NavLink>`也可以这样`<NavLink to="/home" style={({isActive}) => ({color: isActive ? 'red' : ''})}>首页</NavLink><NavLink to="/about" className={({isActive}) => (isActive ? 'link-active' : '')}>关于</NavLink> <Link to="/home">首页</Link><Link to="/about">关于</Link></div></div><hr /><div className="content">`配置映射关系`<Routes><Route path="/" element={<Navigate to="/home" />}></Route><Route path="/home" element={<Home />}><Route path="/home" element={<Navigate to="/home/recommend" />}></Route><Route path="/home/recommend" element={<HomeRecommend />}></Route><Route path="/home/ranking" element={<HomeRanking />}></Route></Route><Route path="/about" element={<About />}></Route><Route path="/order" element={<Order />}></Route><Route path="/category" element={<Category />}></Route><Route path="/login" element={<Login />}></Route>`【* :代表通配符,当以上所有路径都没有匹配的时候,就会匹配到这个 * 】`<Route path="*" element={<NotFound />}></Route></Routes></div><hr /><div className="footer">footer</div></div>)}
}export default App

如果是函数式组件(不使用路由配置)

  • Routes 包裹所有 Route 的容器,负责路由匹配
  • Route 定义,路径与组件的映射关系
  • Link 声明式导航组件(类似 标签,无刷新跳转)
  • NavLink 增强版 Link,可添加激活状态的样式
  • Navigate 用于重定向(如:默认跳转)
  • useNavigate Hook 用于编程式导航(如:按钮点击跳转)

App.jsx

import React from 'react'// 配置映射关系
import { Routes, Route, Link, NavLink, Navigate, useNavigate } from 'react-router-dom'import Home from './pages/Home'
import About from './pages/About'
import Login from './pages/Login'
import NotFound from './pages/NotFound'
import Category from './pages/Category'
import Order from './pages/Order'
import User from './pages/User'import HomeRecommend from './pages/HomeRecommend'
import HomeRanking from './pages/HomeRanking'
import HomeSongMenu from './pages/HomeSongMenu'
import Detail from './pages/Detail'export function App(props) {const navigate = useNavigate()function navigateTo(path) {navigate(path)}return (<div className="app"><div className="header"><span>header</span><div className="nav">`声明式导航`<Link to="/home">首页</Link><Link to="/about">关于</Link><Link to="/login">登录</Link>`编程式导航`<button onClick={e => navigateTo('/category')}>分类</button><span onClick={e => navigateTo('order')}>订单</span>` 带查询参数的导航在 User 组件中通过 useSearchParams() 获取:const [searchParams] = useSearchParams()const name = searchParams.get('name') // "why"const age = searchParams.get('age')   // "18" `<Link to="/user?name=why&age=18">用户</Link></div></div><hr /><div className="content">`配置映射关系`<Routes><Route path="/" element={<Navigate to="/login" />}></Route><Route path="/login" element={<Login />}></Route><Route path="/home" element={<Home />}>`默认子路由重定向`<Route path="/home" element={<Navigate to="/home/recommend" />}></Route><Route path="/home/recommend" element={<HomeRecommend />}></Route><Route path="/home/ranking" element={<HomeRanking />}></Route><Route path="/home/songmenu" element={<HomeSongMenu />}></Route></Route><Route path="/about" element={<About />}></Route><Route path="/order" element={<Order />}></Route><Route path="/category" element={<Category />}></Route>`路由传参 - 方式1 - 动态路由参数如:访问 /detail/123 时,Detail 组件可通过 useParams() 获取 id 参数:const { id } = useParams() // id = "123" 。`<Route path="/detail/:id" element={<Detail />}></Route>`查询参数接收页`	<Route path="/user" element={<User />}></Route>`【* :代表通配符,当以上所有路径都没有匹配的时候,就会匹配到这个 * 】`<Route path="*" element={<NotFound />}></Route></Routes></div><hr /><div className="footer">footer</div></div>)
}export default App

函数式组件(使用路由配置)

App.jsx
import React from 'react'// 配置映射关系
import { Routes, Route, Link, NavLink, Navigate, useNavigate, useRoutes } from 'react-router-dom'import routes from './router'export function App(props) {const navigate = useNavigate()function navigateTo(path) {navigate(path)}return (<div className="app"><div className="header"><span>header</span><div className="nav"><Link to="/home">首页</Link><Link to="/about">关于</Link><Link to="/login">登录</Link><button onClick={e => navigateTo('/category')}>分类</button><span onClick={e => navigateTo('order')}>订单</span><Link to="/user?name=why&age=18">用户</Link></div></div><hr /><div className="content">{/* 配置映射关系 */}{/* 使用路由配置 */}{useRoutes(routes)}</div><hr /><div className="footer">footer</div></div>)
}export default App
router/index.js 路由配置文件
import { Navigate } from 'react-router-dom'
import React from 'react'import Home from '../pages/Home'`打包的时候,如果要对 About、Login 分别单独打包处理,就可以使用懒加载。`
// import About from '../pages/About'
// import Login from '../pages/Login'import NotFound from '../pages/NotFound'
import Category from '../pages/Category'
import Order from '../pages/Order'
import User from '../pages/User'import HomeRecommend from '../pages/HomeRecommend'
import HomeRanking from '../pages/HomeRanking'
import HomeSongMenu from '../pages/HomeSongMenu'
import Detail from '../pages/Detail'`打包的时候,如果要对 About、Login 分别单独打包处理,就可以使用懒加载为什么使用这种形式能够单独打包呢?因为,这是,webpack的特性。`
/*还需要这样处理一下!!!// 打包的时候,如果要对 About、Login 分别单独打包处理<HashRouter><Suspense fallback={<h3>Loading...</h3>}><App /></Suspense></HashRouter>
*/
const About = React.lazy(() => import('../pages/About'))
const Login = React.lazy(() => import('../pages/Login'))const routes = [{path: '/',element: <Navigate to="/home" />},{path: '/home',element: <Home />,children: [{path: '/home',element: <Navigate to="/home/recommend" />},{path: '/home/recommend',element: <HomeRecommend />},{path: '/home/ranking',element: <HomeRanking />},{path: '/home/songmenu',element: <HomeSongMenu />}]},{path: '/about',element: <About />},{path: '/login',element: <Login />},{path: '/category',element: <Category />},{path: '/order',element: <Order />},{path: '/detail/:id',element: <Detail />},{path: '/user',element: <User />},{path: '*',element: <NotFound />}
]export default routes
http://www.dtcms.com/a/282031.html

相关文章:

  • 代谢通路分析:意义、方法与解读
  • 实训十——路由器与TCP/IP模型
  • 筑牢网络安全防线:DDoS/CC 攻击全链路防护技术解析
  • IPv6
  • 构建高可用微服务架构:Istio与Linkerd的深度对比与实战
  • [论文阅读] 人工智能 + 软件工程 | 开源软件中的GenAI自白:开发者如何用、项目如何管、代码质量受何影响?
  • (新手友好)MySQL学习笔记(完):事务和锁
  • 混合参数等效模型
  • 二、CV_AlexNet
  • 牛客:HJ25 数据分类处理[华为机考][哈希][字符串]
  • nextjs+react项目如何代理本地请求解决跨域
  • NSSCTF CVE版签到
  • Win11专业工作站版安装配置要求
  • 实训十一——网络通信原理
  • 【Java】【力扣】94.二叉树的中序遍历
  • 通过 Docker 安装 MySQL
  • 手撕Spring底层系列之:IOC、AOP
  • Web前端性能优化原理与方法
  • 力扣面试150(31/150)
  • React之旅-09 useMemo,优化计算性能的利器
  • Python设计模式深度解析:建造者模式(Builder Pattern)完全指南
  • 浅析BLE/MQTT协议的区别
  • React 源码7:Lane、React和schedule优先级转换
  • Ansible 查看PostgreSQL的版本
  • beautiful-react-hooks库——入门实践常用hook详解
  • React Hooks 数据请求库——SWR使用详解
  • 为来时路,OCM拿证学习和考试
  • 产品经理笔试考试回忆集(2025湖南某国企)
  • 消息中间件(Kafka VS RocketMQ)
  • 每天一个前端小知识 Day 33 - 虚拟列表与长列表性能优化实践(Virtual Scroll)