首页
Preview

在 React18 应用程序中使用 React Router v6详解

什么是 React 路由器?

React Router 是React 应用程序的功能齐全的路由解决方案。它提供预先开发的组件、Hook和实用函数来创建现代路由策略。React Router 项目提供了两个独立的包,用于在 React Web 和 React Native 项目中实现路由。此外,它还为Web版本提供了各种路由机制,例如基于URL路径的路由、URL哈希路由和不可见路由(称为内存路由)。

大多数开发人员使用 React Router v5 创建 React 路由。2021 年,React Router 的维护者发布了 v6,解决了 v5 中存在的一些问题,例如包大小稍大、API 不一致、路径排名问题等。

React Router v6 一致的 API、现代功能(例如,相对嵌套路由、乐观的 UI 功能等)以及对开发人员友好的 Hooks 激励每个 v5 用户和 Reach Router v1.x 用户将他们的应用程序迁移到 React Router v6。

为什么使用 React Router 进行路由?

传统的多页面 Web 应用程序通常具有多个视图文件(页面)来呈现不同的视图,但现代 SPA 使用基于组件的视图。因此,您需要通过路由概念根据 URL 切换组件。React 应用程序开发中出现的每个开发需求都不需要第三方库。尽管如此,类似路由的需求无疑是复杂的,并且需要一个预先开发的库来高效地创建应用程序。

React Router 是基于 React 的 SPA 中最流行且功能齐全的路由库。它具有轻量级的尺寸、易于学习的 API 和编写良好的文档,以便每个 React 开发人员都可以在任何 React 应用程序中高效地实现路由。此外,React Router 现在是一个由Remix维护的项目,拥有积极的开发和开发人员支持。

安装

首先,我们需要安装 react-router-dom。在命令行中运行以下命令:

npm install react-router-dom

或者使用 yarn:

yarn add react-router-dom

基本用法

  • main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import {BrowserRouter } from "react-router-dom";

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  // <React.StrictMode>
    <BrowserRouter>
        <App />
    </BrowserRouter>
  // </React.StrictMode>,
)

在渲染之前,我们将应用组件 App 包裹在 <BrowserRouter> 组件中。这样,我们就可以在整个应用中使用路由功能了。

BrowserRouter 是 React-router-dom 提供的一个组件,它使用 HTML5 的 history API 来实现路由功能。它将应用包裹在一个浏览器路由器中,以便我们可以在应用中使用不同的路由。

  • App.tsx
import {Route, Routes} from "react-router-dom";
function App() {
    return (
        <div className='App'>
            <h1>Hello</h1>
            <Routes>
                <Route path='/' element={<Layout />}>
                    <Route index element={<Home />} />
                    <Route path='about' element={<About />} />
                    <Route path='dashboard' element={<Dashboard />} />
                    <Route path='*' element={<NoMatch />} />
                </Route>
            </Routes>
        </div>
    )
}
  • Routes: 在V6版本中Switch 改为 Routes,外层必须加上Routes
  • elementcomponents 改用 elementelement自行更换成元件名称即可

v6版本改动的地方

  • Switch 改为使用 Routes

新版外层一定要加上 Routes

import {  Routes, Route } from 'react-router-dom'
    <Routes>
         <Route element={<Home />} path={'/'}></Route>
         <Route element={List} path='/list'></Route>
    </Routes>
  • components 改用 element
<Route element={<Home />} path={'/'}></Route>
  • useHistory 改成 useNavigate
import { useNavigate } from "react-router-dom";
const ABOUT = () => {
    const navigate = useNavigate()
    const onClick = () => {
        navigate('/')
    }
    return (
        <div>
            <button onClick={onClick}>BACK</button>
        </div>
    )
}

进阶运用

  • Outlet outlet是应用于嵌套路由的占位,可以保证子路由共享父路由的界面而不会覆盖。 如下面列子:
import React from 'react'
import './App.css'
import {
    Routes,
    Route,
    Link,
    useNavigate,
    Outlet,
    useLocation,
} from 'react-router-dom'

const Home = () => {
    return (
        <div>
            <ul>
                <li>HOME</li>
                <li>
                    <Link to='/about'>About</Link>
                </li>
                <li>
                    <Link to='/list'>List</Link>
                </li>
            </ul>
        </div>
    )
}
const About = () => {
    const navigate = useNavigate()
    const onClick = () => {
        navigate('/')
    }
    return (
        <div>
            <button onClick={onClick}>BACK</button>
        </div>
    )
}

const Child1 = () => {
    return <div>Child1</div>
}
const Child2 = () => {
    return <div>Child2</div>
}

const List = () => {
    return (
        <div>
            list 页面
            <Menus1 />
            <Container />
        </div>
    )
}
const Container = () => {
    return (
        <div>
            <Outlet />
        </div>
    )
}
const Menus1 = () => {
    return (
        <div>
            <Link to={'/list/child1'}> one </Link>
            <Link to={'/list/child2'}> two </Link>
        </div>
    )
}

function App() {
    return (
        <div className='App'>
       
                <Routes>
                    <Route element={<Home />} path={'/'}></Route>
                    <Route element={<About />} path='/about'></Route>
                    <Route element={<List />} path='/list'>
                        <Route element={<Child1 />} path='/list/child1'></Route>
                        <Route element={<Child2 />} path='/list/child2'></Route>
                    </Route>
                </Routes>
          
        </div>
    )
}
export default App
  • useLocation 抓取网址中的消息
const location = useLocation()
console.log(location)
  • useParams 抓取动态参数
const params = useParams()
console.log(params, 'params')
  • useSearchParams 取得网址参数
const [getParams, setParam] = useSearchParams()
const name = getParams.getAll('name')

(getParams 取得参数 / setParam 设置参数)

  • No Match!如果网址没有 match 的话
<Route
      path='*'
      element={
               <main style={{ padding: '1rem' }}>
                     <p>There's nothing here!</p>
               </main>
               }
/>
  • 使用useRoutes 更灵活的配置 router (路由)

将在App.tsx里面的路由封装

const routeConfig = [
    {
        path: '/',
        element: <Home />,
    },
    { path: '/about', element: <About /> },
    {
        path: '/list',
        element: <List />,
        children: [
            { path: '/list/child1', element: <Child1 /> },
            { path: '/list/child2/:id', element: <Child2 /> },
        ],
    },
]

使用方法

const element = useRoutes(routeConfig)
    return (
        <div>{element}</div>
)

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
Hedy
大家好!我是一位前端开发工程师,拥有6年以上的前端开发经验。我熟练掌握HTML、CSS、JavaScript等语言,能够灵活运用各种前端框架,如Vue、React、Uniapp、Flutter等。我注重理论与实践相结合,能够为学员提供丰富的案例和实践项目,并以生动、易懂的语言为学员讲解前端开发的核心知识和技能。我不仅注重传授技能,更关注学员的职业发展,希望通过我的教学,帮助学员成为一名优秀的前端开发工程师。

评论(0)

添加评论