React-Router

117 阅读2分钟

一、认识React-Router

  • React-Router6.x已经非常稳定

二、Router的基本使用

1. 安装路由

  • npm install react-router-dom

2. HashRouter/BrowserRouter

使用HashRouter/BrowserRouter对App进行包裹,开启路由

  • Router包含了对路径改变的监听,并且会将相应的路径传递给子组件
  • HashRouter使用hash模式
  • BrowserRouter使用history模式
// --- index.js ---
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(
  <React.StrictMode>
    <HashRouter>
       <App />
    </HashRouter> 
  </React.StrictMode>
);

3. 路由映射配置

  • Routes:包裹所有的Route,在其中匹配一个路由
  • Route:Route用于路径的匹配
    • path属性:用于设置匹配到的路径
    • element属性:设置匹配到路径后,渲染的组件(Router5.x使用的是component)
    • exact:精准匹配(Router6.x不再支持该属性)

4. 路由的配置和跳转

  • Link
    • to属性:用于设置跳转到的路径
  • NavLink
    • to属性
    • style:传入函数,函数接受一个对象,包含isActive属性
    • className:传入函数,函数接受一个对象,包含isActive属性

5. Navigate导航

  • Navigate用于路由的重定向,当这个组件出现时,就会执行跳转到对应的to路径中
import React, { PureComponent } from 'react'
import { Route, Routes, NavLink, Link, Navigate } from "react-router-dom"
import Home from './pages/Home'
import About from './pages/About'
import NotFound from './pages/NotFound'

export class App extends PureComponent {
  render() {
    return (
      <div className='app'>
        <div className='header'>
          <span>Header</span>
          <div className='nav'>
            <Link to="/home">首页</Link>
            <Link to="/about">关于</Link>
          </div>
          <hr />
        </div>
        <div className='content'>
          {/* 映射关系:path => Component */}
          <Routes>
            <Route path='/' element={<Navigate to="/home"/>}/>
            <Route path='/home' element={<Home/>}/>
            <Route path='/about' element={<About/>}/>
            <Route path='*' element={<NotFound/>}/>
          </Routes>
        </div>
        <div className='footer'>
          <hr />
          Footer
        </div>
      </div>
    )
  }
}

export default App

三、Router的路由嵌套

<Routes>
    <Route path='/' element={<Navigate to="/home"/>}/>
    <Route path='/home' element={<Home/>}>
      <Route path='/home' element={<Navigate to="/home/recommend"/>}/>
      <Route path='/home/recommend' element={<HomeRecommend/>}/>
      <Route path='/home/ranking' element={<HomeRanking/>}/>
    </Route>
</Routes>

四、Router的参数传递

1. 传递参数的两种方式

  • 动态路由的方式
    • /about/:id
  • search传递参数
    // --- 传递参数 ---
    <Link to="user?name=kobe&age=18">用户</Link>
    // --- 获取参数 ---
    const [searchParams] = useSearchParams()
    const query = Object.fromEntries(searchParams)
    

五、Router的配置方式

// --- router/index.js ---
import React from "react"
import { Navigate } from "react-router-dom"
import Home from '../pages/Home'
import NotFound from '../pages/NotFound'
import HomeRecommend from '../pages/HomeRecommend'
import HomeRanking from '../pages/HomeRanking'

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: "/about",
    element: <About/>
  }, 
  {
    path: "/login",
    element: <Login/>
  },
  {
    path: "*",
    element: <NotFound/>
  },
]

export default routes
// --- App.jsx ---
import React from 'react'
import { Route, Routes, Link, 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>
            
            <span onClick={e => navigateTo("/about")}>订单</span>

            <Link to="/user?name=why&age=18">用户</Link>
          </div>
          <hr />
        </div>
        <div className='content'>
          {useRoutes(routes)}
        </div>
        <div className='footer'>
          <hr />
          Footer
        </div>
      </div>
    )
}

export default App
// --- index.js ---
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { HashRouter } from "react-router-dom"

// 如果对某些组件进行了懒加载,需要用Suspense进行包裹
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <HashRouter>
      <React.Suspense fallback={<h3>Loading</h3>}>
        <App />
      </React.Suspense>
    </HashRouter> 
  </React.StrictMode>
);