目录:
1 认识React-Router
2 Router的基本使用
3 Router的路由嵌套
4 Router的代码跳转
5 Router的参数传递
6 Router的配置方式
一、认识React-Router
二、Router的基本使用
1、在app.jsx的index.js文件里面引入router和严格模式
2、配置路由映射 ,在需要使用router的组件里面使用Router和route组件以及Link组件,通过点击Link组件来跳转url
import { Link, Route, Routes } from 'react-router-dom'
3、通过给的NavLink组件来做到点击之后的NavLink内容发生css样式的变化,后续使用button来做跳转的时候比较好,可以自己控制跳转,NavLink不好控制。
通过NavLink组件被点击之后会给组件添加.active的类名,可以在css文件里面添加该类的样式从而控制NavLink被点击之后的样式。
另外一种变色的方法:
如果怕这个类名会冲突,可以使用下面的方法来实现改变样式:
4、重定向(Navigate组件)使用举例,登录成功之后跳转到首页:
重定向还有一个作用就是可以在网站默认页/的时候主动跳转到你给定的地址,下图是在页面:
在用户进入到没有页面的路由路径的时候,我们可以设置notfound页面来提示用户没有此页面:不能限定path路径,可以通过*来设置通配,当url地址不是上面的任何一个的时候跳转到notfound页面。
三、Router的路由嵌套
1、在app.jsx组件里面添加:因为跳转到/home的时候需要重定向子组件跳转到一个默认的子组件来显示东西,不然跳转过去没有东西。
在/home的组件里面添加link点击跳转的按钮和占位符outlet:
四、Router的代码跳转
注意:useNavigate是个函数,不可以在类组件里面调用,可以在函数式组件里面使用
由于link组件渲染出来是个a标签,不能给属性,所以需要手动跳转路由的方式来改变标签类型:
1、在函数式组件中使用手动跳转路由
引入useNavigate并使用,
2、类组件中实现手动跳转:(需要使用增强)
(1)创建hoc文件夹,文件夹底下放
index.js代码:
import withRouter from "./with_router"; export { withRouter }
with_router.js代码:
import { useState } from "react" import { useLocation, useNavigate, useParams, useSearchParams } from "react-router-dom" // 高阶组件: 函数 function withRouter(WrapperComponent) { return function(props) { // 1.导航,为了类组件实现手动跳转的 const navigate = useNavigate() // 2.动态路由的参数: /detail/:id const params = useParams() // 3.查询字符串的参数: /user?name=why&age=18 const location = useLocation() const [searchParams] = useSearchParams() const query = Object.fromEntries(searchParams) const router = { navigate, params, location, query } return <WrapperComponent {...props} router={router}/> } } export default withRouter
需要使用增强的组件,需要手动跳转路由的组件代码:
import React, { PureComponent } from 'react' import { Link, Outlet } from 'react-router-dom' import { withRouter } from "../hoc" export class Home extends PureComponent { //跳转的方法 navigateTo(path) { const { navigate } = this.props.router navigate(path) } render() { return ( <div> <h1>Home Page</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 withRouter(Home)
五、Router的参数传递
第一种方法是动态路由的方式传递可见的参数,需要使用增强:
(1)需要跳转页面的组件使用上面手动跳转的方式来在url里面添加参数
import React, { PureComponent } from 'react' import { withRouter } from "../hoc" export class HomeSongMenu extends PureComponent { constructor(props) { super(props) this.state = { songMenus: [ { id: 111, name: "华语流行" }, { id: 112, name: "古典音乐" }, { id: 113, name: "民谣歌曲" }, ] } } NavigateToDetail(id) { const { navigate } = this.props.router navigate("/detail/" + id) } render() { const { songMenus } = this.state return ( <div> <h1>Home Song Menu</h1> <ul> { songMenus.map(item => { return <li key={item.id} onClick={e => this.NavigateToDetail(item.id)}>{item.name}</li> }) } </ul> </div> ) } } export default withRouter(HomeSongMenu)
(2)在hoc文件夹里的增强组件的函数里面添加把参数传递到router自定义属性里面。
import { useState } from "react" import { useLocation, useNavigate, useParams, useSearchParams } from "react-router-dom" // 高阶组件: 函数 function withRouter(WrapperComponent) { return function(props) { // 1.导航 const navigate = useNavigate() // 2.动态路由的参数: /detail/:id const params = useParams() // 3.查询字符串的参数: /user?name=why&age=18 const location = useLocation() const [searchParams] = useSearchParams() const query = Object.fromEntries(searchParams) const router = { navigate, params, location, query } return <WrapperComponent {...props} router={router}/> } } export default withRouter
(3)在跳转到的组件里面填写接收的方法
import React, { PureComponent } from 'react' import { withRouter } from '../hoc' export class Detail extends PureComponent { render() { const { router } = this.props const { params } = router return ( <div> <h1>Detail Page</h1> <h2>id: {params.id}</h2> </div> ) } } export default withRouter(Detail)
第二种方法:拼接参数,查询字符串的参数
(1)可以通过useLocation来获取参数,但是很麻烦,不建议用
(2)还可以通过useSearchParams
在hoc的组件增强函数里面添加下面这个方法
然后在需要使用拼接参数的值:
import React, { PureComponent } from 'react' import { withRouter } from '../hoc' export class User extends PureComponent { render() { const { router } = this.props const { query } = router return ( <div> <h1>User: {query.name}-{query.age}</h1> </div> ) } } export default withRouter(User)
六、Router的配置方式
上面提到的router都是配置在app.jsx文件里面的,不好管理和配置,于是我们和vue一样设置一个名字叫router的文件夹来存放对应的配置信息:
文件夹:
index.js的内容是:
从原来的
变成了下面的:
import Home from '../pages/Home' import HomeRecommend from "../pages/HomeRecommend" import HomeRanking from "../pages/HomeRanking" import HomeSongMenu from '../pages/HomeSongMenu' // import About from "../pages/About" // import Login from "../pages/Login" import Category from "../pages/Category" import Order from "../pages/Order" import NotFound from '../pages/NotFound' import Detail from '../pages/Detail' import User from '../pages/User' import { Navigate } from 'react-router-dom' import React from 'react' 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
在App.jsx文件夹里面需要使用useRouters来生成和原来一样的router结构:
不能直接用 {useRoutes}要写成下面的形式
{useRoutes(routes)}
路由的懒加载(单独打包,提升性能):
在之前配置的router文件夹底下的index.js文件里面把需要懒加载的组件import引入的形式写成:
其次,在App.jsx文件对应的index.js里面的<app/>需要被组件<Suspense fallback={
Loading
}></Suspense>包裹才不会报错。Suspense组件的作用是因为懒加载需要下载对应的组件文件,这个时候提示消息Loading...import { Suspense } from "react"
版权归原作者 木公176 所有, 如有侵权,请联系我们删除。