React Router v6的基本使用


前言

路由干啥的就先不介绍了

Router的基本使用

安装路由

npm install react-router-dom
npm install @types/react-router-dom

配置路由

在入口文件导入 BrowserRouterHashRouter 组件

// index.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';

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

root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

reportWebVitals()

基本用法

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

function App() {
  return (
    <div>
      <Link to='/'>Home</Link>
      <Link to='/about'>About </Link>

      <Routes>
        <Route path='/about' element={<About />} />
        <Route path='/' element={<Home />} />
      </Routes>
    </div>
  )
}

export default App;

Router的用法详解

默认路由 index

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

function App() {
  return (
    <div>
      <Link to='/home'>Home</Link>
      <Link to='/about'>About </Link>

      <Routes>
        <Route path='/about' element={<About />} />
        <Route path='/home' element={<Home />} />
        <Route index element={<Home />} />
      </Routes>
    </div>
  )
}

export default App;

上面这个例子中,如果使用index指定默认路由为Home组件,我们打开网页时,就会默认显示Home组件。
如果我们不使用index指定默认路由,假如当前网页地址为http://127.0.0.1:3000Home组件需要匹配 urlhttp://127.0.0.1:3000/home,而About组件需要匹配 urlhttp://127.0.0.1:3000/about,而当前 urlhttp://127.0.0.1:3000,匹配不了,所以Home组件和About组件都不会直接显示在页面上,需要我们点击对应的 Link 才会显示对应的组件。

路由重定向 Navigate

// app.tsx
import React from 'react'
import { Link, Navigate, Route, Routes } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'

function App() {
  return (
    <div>
      <Link to='/home'>Home</Link>
      <Link to='/about'>About </Link>

      <Routes>
        <Route path='/about' element={<About />} />
        <Route path='/home' element={<Home />} />
        <Route path='/' element={<Navigate to='/home' />} />
      </Routes>
    </div>
  )
}

export default App;

上面这个例子中,Navigate会将http://127.0.0.1:3000/重定向为http://127.0.0.1:3000/home,所以打开网页就会显示Home组件
注意在上面的两个案例中,使用index和Navigate都网页打开就默认显示了Home组件,但是其中还是有一些区别的:

  • 使用index,打开网页时,url还是为http://127.0.0.1:3000
  • 使用和Navigate,打开网页时 url 会自动跳转到http://127.0.0.1:3000/home

选中样式 NavLink

我们希望点击HOME跳转到Home组件,点击ABOUT跳转到About组件,但同时还希望显示Home组件时,HOME能有一个样式(比如HOME这几个字的背景变为红色),显示About组件时,ABOUT能有一个样式,这个时候就需用用到NavLink了

// app.tsx
import React from 'react'
import { Navigate, NavLink, Route, Routes } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'
import './App.css'

function App() {
  return (
    <div>
      <NavLink to='/home' className={({ isActive }) => isActive ? "selected" : ""}>HOME</NavLink>
      <NavLink to='/about' className={({ isActive }) => isActive ? "selected" : ""}>ABOUT</NavLink>
      <Routes>
        <Route path='/about' element={<About />} />
        <Route path='/home' element={<Home />} />
        <Route path='/' element={<Navigate to='/home' />} />
      </Routes>
    </div>
  )
}

export default App;
/* App.css */
.selected {
  background-color: red;
}

({ isActive }) => isActive ? "selected" : ""中,:前面前面写选中的样式,:后面写未选择的样式。

编程式路由导航 useNavigate

前面所讲的路由跳转方式(LinkNavLink)都是声明式路由导航,现在我们有这么一个需求,点击某个按按钮(<button></button>)跳转到特定页面,就需要用到编程式路由导航useNavigate

// app.tsx
import React from 'react'
import { Route, Routes, useNavigate } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'

function App() {
  const navigate = useNavigate();

  function goToHome() {
    navigate('/home');
  }

  function goToAbout() {
    navigate('/about');
  }

  return (
    <div>
      <button onClick={goToHome}>Home</button>
      <button onClick={goToAbout}>About</button>
      
      <Routes>
        <Route path='/about' element={<About />} />
        <Route path='/home' element={<Home />} />
      </Routes>
    </div>
  )
}

export default App;

路由嵌套 Outlet

假如路由组件Home,下面还有两个路由组件FristHomeSecondHome,这个时候就需要用到路由嵌套

// app.tsx
// app.tsx
import React from 'react'
import { Link, Route, Routes, } from 'react-router-dom'
import About from './pages/About'
import FristHome from './pages/FirstHome'
import Home from './pages/Home'
import SecondHome from './pages/SecondHome'

function App() {
  return (
    <div>
      <Link to='/home'>Home</Link>
      <Link to='/about'>About </Link>

      <Routes>
        <Route path='/about' element={<About />} />
        <Route path='/home' element={<Home />} >
          <Route path='first' element={<FirstHome />} />
          <Route path='second' element={<SecondHome />} />
        </Route>
      </Routes>
    </div>
  )
}

export default App;

Outlet组件主要起到一个占位用作用,用于标记子路由显示的位置。

// pages/Home.tsx
import React from 'react'
import { Link, Outlet } from 'react-router-dom'

function Home() {
    return (
        <div>
            <h1>Home 组件</h1>
            <Outlet />
            <Link to='first'>FristHome</Link>
            <Link to='second'>SecondHome </Link>
        </div>
    )
}

export default Home

路由表 useRoutes

普通使用

// router/routerCfg
import About from "../pages/About";
import Home from "../pages/Home";

const routerCfg = [
    {
        path: '/home',
        element: <Home />,
    },
    {
        path: '/about',
        element: <About />
    },
]

export default routerCfg;
// app.tsx
import React from 'react'
import { Link, Route, Routes, useRoutes, } from 'react-router-dom'
import routerCfg from './router/routerCfg';

function App() {
  return (
    <div>
      <Link to='/home'>Home</Link>
      <Link to='/about'>About </Link>

      {useRoutes(routerCfg)}
    </div>
  )
}

export default App;

重定向

// router/routerCfg
import { Navigate } from "react-router-dom";
import About from "../pages/About";
import Home from "../pages/Home";

const routerCfg = [
    {
        path: '/home',
        element: <Home />,
    },
    {
        path: '/about',
        element: <About />
    },
    {
        path: '/',
        element: <Navigate to='/home' />
    }
]

export default routerCfg;

路由嵌套

// router/routerCfg
import { Navigate } from "react-router-dom";
import About from "../pages/About";
import FristHome from "../pages/FirstHome";
import Home from "../pages/Home";
import SecondHome from "../pages/SecondHome";

const routerCfg = [
    {
        path: '/home',
        element: <Home />,
        children: [
            {
                path: 'first',
                element: <FristHome />
            },
            {
                path: 'second',
                element: <SecondHome />
            }
        ]
    },
    {
        path: '/about',
        element: <About />
    },
    {
        path: '/',
        element: <Navigate to='/home' />
    }
]

export default routerCfg;

路由懒加载

// router/routerCfg
import React from "react";
import { Navigate } from "react-router-dom";
const About = React.lazy(() => import('../pages/About'));
const FristHome = React.lazy(() => import('../pages/FirstHome'));
const Home = React.lazy(() => import('../pages/Home'));
const SecondHome = React.lazy(() => import('../pages/SecondHome'));

const routerCfg = [
    {
        path: '/home',
        element: <Home />,
        children: [
            {
                path: 'first',
                element: <FristHome />
            },
            {
                path: 'second',
                element: <SecondHome />
            }
        ]
    },
    {
        path: '/about',
        element: <About />
    },
    {
        path: '/',
        element: <Navigate to='/home' />
    }
]

export default routerCfg;
// app.tsx
import React, { Suspense } from 'react'
import { Link, useRoutes } from 'react-router-dom'
import routerCfg from './router/routerCfg';

function App() {
  return (
    <div>
      <Link to='/home'>Home</Link>
      <Link to='/about'>About </Link>
      
      <Suspense fallback={<div>Loading...</div>}>
        {useRoutes(routerCfg)}
      </Suspense>
    </div>
  )
}

export default App;

路由传递参数

params参数 useParams

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


function App() {
  const id = '233';
  const name = 'baiyin';

  return (
    <div>
      <Link to={`/home/${id}/${name}`}>Home</Link>
      <Link to='/about'>About </Link>

      <Routes>
        <Route path='/home/:id/:name' element={<Home />} />
        <Route path='/about' element={<About />} />
      </Routes>
    </div>
  )
}

export default App;
// pages/Home.tsx
import React from 'react'
import { useParams } from 'react-router-dom'

function Home() {
    //获取params参数的消息
    const { id, name } = useParams();

    return (
        <div>
            <h1>Home 组件</h1>
            <h2>{id}---{name}</h2>
        </div>
    )
}

export default Home

search参数 useSearchParams

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


function App() {
  const id = '233';
  const name = 'baiyin';

  return (
    <div>
      <Link to={`/home?id=${id}&name=${name}`}>Home</Link>
      <Link to='/about'>About </Link>

      <Routes>
        <Route path='/home' element={<Home />} />
        <Route path='/about' element={<About />} />
      </Routes>
    </div>
  )
}
export default App;
// pages/Home.tsx
import React from 'react'
import { useSearchParams } from 'react-router-dom'

function Home() {
    // 接收serach参数
    const [search, setSearch] = useSearchParams();
    const id = search.get("id");
    const name = search.get("name");
    
    return (
        <div>
            <h1>Home 组件</h1>
            <h2>{id}---{name}</h2>
        </div>
    )
}

export default Home

state参数 useLocation

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


function App() {
  const id = '233';
  const name = 'baiyin';

  return (
    <div>
      <Link to={`/home`} state={{ id: id, name: name }}>Home</Link>
      <Link to='/about'>About </Link>

      <Routes>
        <Route path='/home' element={<Home />} />
        <Route path='/about' element={<About />} />
      </Routes>
    </div>
  )
}

export default App;
// pages/Home.tsx
import React from 'react'
import { useLocation, useSearchParams } from 'react-router-dom'

function Home() {
    // 接收state参数
    const { state: { id, name } } = useLocation();

    return (
        <div>
            <h1>Home 组件</h1>
            <h2>{id}---{name}</h2>
        </div>
    )
}

export default Home

使用useNavigate传递state参数,接收还是用useLocation

// app.tsx
import React from 'react'
import { Route, Routes, useNavigate } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'

function App() {
  const navigate = useNavigate();
  const id = '233';
  const name = 'baiyin';

  function goToHome() {
    navigate('/home', {
      replace: false,
      state: {
        id: id,
        name: name,
      }
    });
  }

  function goToAbout() {
    navigate('/about');
  }

  return (
    <div>
      <button onClick={goToHome}>Home</button>
      <button onClick={goToAbout}>About</button>

      <Routes>
        <Route path='/about' element={<About />} />
        <Route path='/home' element={<Home />} />
      </Routes>
    </div>
  )
}

export default App;

注意:state参数最好不要用来的传递react state里的需要频繁变动,且需要路由组件做出相应的反馈的数据,state参数需要点击链接,才能向下传递数据。
而传递参数使用路由表的话,把Routes里面的转写成路由表就行了。

注意点

  • 默认情况下就是精确匹配(匹配完整路径),如果像匹配某某一部分,在路径后面加 /*

  • Route能够自动找出最优的匹配路径,Route先后顺序不重要

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值