React(八)React-Router

基本使用

1.安装:

npm install react-router-dom

2.设置路由模式:HashRouter/BrowserRouter

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { HashRouter } from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  
    
      
    
  
);

3.路由配置和跳转

  • path属性:用于设置匹配到的路径
  • element属性:设置匹配到路径后,渲染的组件(Router5.X中使用component属性)
  • exact:精确匹配,只有精准匹配到完全一致的路径才渲染对应组件(Router6.X已经不支持)

使用Link组件:最终会被渲染成a元素

import React, { PureComponent } from 'react'
import { Link, Route, Routes } from 'react-router-dom'
import Home from './pages/Home'
import About from './pages/About'
import Profile from './pages/Profile'

export class App extends PureComponent {
  render() {
    return (
      
Home About Profile
{/* 配置映射关系:path => Component */} } /> } /> } />
Footer
) } } export default App

NavLink:当前路由选中时,会自动添加一个active的类

4.Navigate导航:可用于路由重定向

{/* 配置映射关系:path => Component */} {/* 当路径为"/"时,重定向到"/home" */} } /> } /> } /> {/* 当路径匹配不到时,重定向到"/NotFound" */} } />

路由嵌套

需求:在Home组件中再嵌套两个子组件HomeRecommend和HomeRanking

React(八)React-Router_第1张图片

1.路由嵌套配置

{/* 配置映射关系:path => Component */} } /> } > } /> } /> } /> } /> } /> } /> } />

2.展示二级路由对应组件

Home

推荐 排行
{/* 占位的组件 */}

手动路由跳转

Link渲染出来的是a标签,如果我们想要其它的标签,那就只能自己来操作了

函数式组件跳转

import React from 'react'
import { Link, Navigate, Route, Routes, useNavigate } from 'react-router-dom'
import Order from './pages/Order'
import Category from './pages/Category'

export function App (props) {
  const navigate = useNavigate()
  function navigateTo(path) {
    navigate(path)
  }
  return (
    
navigateTo("/order")}>订单

} /> } /> } />

Footer
) } export default App

类组件跳转

1.封装一个高阶组件,给类组件注入这个hook,然后通过props就能调用并传参

import { useNavigate } from "react-router-dom"
// 封装一个高阶组件
function withRouter(WrappedComponent) {
  return function(props) {
    const navigate = useNavigate()
    const router = {navigate}
    return 
  }
}

export default withRouter

2.在组件中使用

import React, { PureComponent } from 'react'
import { Link,  Outlet} from 'react-router-dom'
import withRouter from '../hoc/with_router';

export class Home extends PureComponent {
  navigateTo(path) {
    console.log(path);
    const {navigate} = this.props.router
    navigate(path)
  }
  render() {
    return (
      

Home

推荐 排行
{/* 占位的组件 */}
) } } export default withRouter(Home)

路由跳转传参

动态路由传参

1.配置路由路径

} />

2.点击后跳转到详情并携带id参数

高阶组件-src/hoc/with_router.js

import { useNavigate, useParams, useSearchParams } from "react-router-dom"
// 封装一个高阶组件
function withRouter(WrappedComponent) {
  return function(props) {
    // 1.导航参数
    const navigate = useNavigate()
    // 2.动态路由参数
    const params = useParams()
    // 3.查询字符串的参数
    const [searchParams] = useSearchParams()
    const query = Object.fromEntries(searchParams)
    const router = {navigate,params,query}
    return 
  }
}

export default withRouter

HomeSongMenu.jsx: 

import React, { PureComponent } from 'react'
import withRouter from '../hoc/with_router';

export class HomeSongMenu extends PureComponent {
  constructor(props) {
    super(props)
    this.state={
      songMenus:[
        {id:111,name:"华语流行"},
        {id:112,name:"古典音乐"},
        {id:113,name:"民谣歌曲"},
        {id:114,name:"摇滚音乐"},
        {id:115,name:"R&B"}
      ]
    }
  }

  NavigateTo(id) {
    const {navigate} = this.props.router;
    navigate('/detail/' + id)
  }
  render() {
    const {songMenus} = this.state; 
    return (
      

HomeSongMenu

    {songMenus.map((item,index) => { return
  • this.NavigateTo(item.id)} key={item.id}>{item.name}
  • })}
) } } export default withRouter(HomeSongMenu)

query传参

import React from 'react'
import { Link, Navigate, Route, Routes, useNavigate } from 'react-router-dom'
import User from './pages/User'

export function App (props) {
  const navigate = useNavigate()
  function navigateTo(path) {
    navigate(path)
  }
  return (
    
用户

{/* 配置映射关系:path => Component */} } /> } />

Footer
) } export default App

User.jsx:

import React, { PureComponent } from 'react'
import withRouter from '../hoc/with_router'

export class User extends PureComponent {
  render() {
    const {router} = this.props
    const {query} = router
    return (
      
User:{query.name}-{query.age}
) } } export default withRouter(User)

路由配置

将App.js中配置的路由单独抽取到router/index.js文件中

import { Navigate } from "react-router-dom"
import Home from "../pages/Home"
import About from '../pages/About'
import Profile from '../pages/Profile'
import Login from '../pages/Login'
import NotFound from '../pages/NotFound'
import HomeRecommend from '../pages/HomeRecommend'
import HomeRanking from '../pages/HomeRanking'
import HomeSongMenu from '../pages/HomeSongMenu'
import Order from '../pages/Order'
import Category from '../pages/Category'
import Detail from '../pages/Detail'
import User from '../pages/User'

const routes = [
  {
    path:"/",
    element:
  },
  {
    path:"/home",
    element:,
    children:[
      {
        path:"/home/recommend",
        element:
      },
      {
        path:"/home/rank",
        element:
      },
      {
        path:"/home/songmenu",
        element:
      }
    ]
  },
  {
    path:"/about",
    element:
  },
  {
    path:"/profile",
    element:
  },
  {
    path:"/login",
    element:
  },
  {
    path:"/category",
    element:
  },
  {
    path:"/order",
    element:
  },
  {
    path:"/detail/:id",
    element:
  },
  {
    path:"/user",
    element:
  },
  {
    path:"*",
    element:
  }
]

export default routes

在根组件中使用:App.jsx

import {useRoutes } from 'react-router-dom'
{/* 配置映射关系:path => Component */} {/* useRoutes()是一个函数调用,所有可以在类组件中使用 */} {useRoutes(routes)}

路由懒加载

可单独打包,匹配到该路径才会下载对应的文件——性能优化

import { Navigate } from "react-router-dom";
import React, { lazy } from 'react';

// 使用 React.lazy 进行懒加载
const Home = lazy(() => import('../pages/Home'));
const About = lazy(() => import('../pages/About'));
const Profile = lazy(() => import('../pages/Profile'));
const Login = lazy(() => import('../pages/Login'));
const NotFound = lazy(() => import('../pages/NotFound'));
const HomeRecommend = lazy(() => import('../pages/HomeRecommend'));
const HomeRanking = lazy(() => import('../pages/HomeRanking'));
const Order = lazy(() => import('../pages/Order'));
const Category = lazy(() => import('../pages/Category'));
const HomeSongMenu = lazy(() => import('../pages/HomeSongMenu'));
const Detail = lazy(() => import('../pages/Detail'));
const User = lazy(() => import('../pages/User'));

const routes = [
  {
    path: "/",
    element: 
  },
  {
    path: "/home",
    element: ,
    children: [
      {
        path: "recommend",
        element: 
      },
      {
        path: "rank",
        element: 
      },
      {
        path: "songmenu",
        element: 
      }
    ]
  },
  {
    path: "/about",
    element: 
  },
  {
    path: "/profile",
    element: 
  },
  {
    path: "/login",
    element: 
  },
  {
    path: "/category",
    element: 
  },
  {
    path: "/order",
    element: 
  },
  {
    path: "/detail/:id",
    element: 
  },
  {
    path: "/user",
    element: 
  },
  {
    path: "*",
    element: 
  }
];

export default routes;

导入Suspense并包裹根组件,当匹配的组件还未加载成功时,可显示fallback中的内容

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { HashRouter } from 'react-router-dom';
import { Suspense } from 'react';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    
      加载中
}> );

你可能感兴趣的:(React学习,react.js,前端)