0
点赞
收藏
分享

微信扫一扫

【React Router 6 快速上手一】重定向Navigate / useRoutes路由表 / 嵌套路由Outlet

求索大伟 2022-08-15 阅读 95

前言

在这里插入图片描述

文章目录

概述

React Router 以三个不同的包发布到 npm 上,它们分别为:

与React Router 5.x 版本相比,改变了什么?

1. 一级路由Routes

<BrowserRouter>

  1. 说明:<BrowserRouter> 用于包裹整个应用,v6版本中,依然需要用<BrowserRouter>标签将App组件包裹起来。
  2. 示例代码:
import React from 'react';
import ReactDOM from 'react-dom/client'
import App from './App'
import { BrowserRouter } from 'react-router-dom'

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

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

<HashRouter>

  1. 说明:作用与<BrowserRouter>一样,但<HashRouter>修改的是地址栏的hash值。
  2. 备注:6.x版本中<HashRouter><BrowserRouter> 的用法与 5.x 相同。

基本使用

这里还是以之前学过的react-router-dom@5的案例来分析。

App.jsx

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

export default function App() {
  return (
    <div>
      <div className="row">
        <div className="col-xs-offset-2 col-xs-8">
          <div className="page-header">
            <h2>React Router Demo</h2>
          </div>
        </div>
      </div>
      <div className="row">
        <div className="col-xs-2 col-xs-offset-2">
          <div className="list-group">
            {/* 路由链接 */}
            <NavLink className="list-group-item" to="/about">About</NavLink>
            <NavLink className="list-group-item" to="/home">Home</NavLink>
          </div>
        </div>
        <div className="col-xs-6">
          <div className="panel">
            <div className="panel-body">
              {/* 注册路由 */}
              <Routes>
                <Route path='/about' element={<About />} />
                <Route path='/home' element={<Home />} />
              </Routes>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

<Routes/> 与 <Route/>

2. 重定向Navigate

在v5版本中,路由的重定向使用的是Redirect,在v6版本中使用的是Navigate

v5版本的写法:
import { Redirect } from 'react-router-dom'
<Redirect to="/home" />

v6版本的写法:
import { Navigate } from 'react-router-dom'
<Route path='/' element={<Navigate to='/about' />} />

作用

只要<Navigate>组件被渲染,就会修改路径,切换视图。

replace属性用于控制跳转模式(push 或 replace,默认是push)。

路由的跳转有两种模式,push和replace,push模式会将这个url压入路由history栈顶; 而replace模式会将栈顶的url替换 。

Navigate组件可以设置replace的值为true或false,默认值为false,所以默认为push跳转。

3. NavLink高亮

在v5版本中,实现NavLink高亮使用的是NavLink组件标签中的activeClassName属性,当你点击NavLink标签时,加哪个样式的类名。

<NavLink activeClassName='demo' className="list-group-item" to="/about">About</NavLink>
<NavLink activeClassName='demo' className="list-group-item" to="/home">Home</NavLink>

在v6版本中,想要实现自定义的类名,需要把className的值写成一个函数

//高亮样式
<style>
    .demo {
      background-color: orange !important;
      color: white !important;
    }
</style>
<NavLink className={({ isActive }) => 
{ return isActive ? 'list-group-item demo' : 'list-group-item' }} to="/about">
About
</NavLink>

/*
	默认情况下,当Home的子组件匹配成功,Home的导航也会高亮,
	当NavLink上添加了end属性后,若Home的子组件匹配成功,则Home的导航没有高亮效果。
*/
<NavLink to="home" end >home</NavLink>

代码优化实现复用

将ClassName的值封装成一个函数

function computedClassName({ isActive }) {
  return isActive ? 'list-group-item demo' : 'list-group-item'
}
...
<NavLink className={computedClassName} to="/about">About</NavLink>

4. useRoutes()路由表

作用

在src下新建一个routes文件夹,专门用于维护路由表,应用中的路由都存放在路由表中。

在这里插入图片描述

src/routes/index.js

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

export default [
  // 路由表
  {
    path: '/about',
    element: <About />
  },
  {
    path: '/home',
    element: <Home />
  },
  {
    path: '/',
    element: <Navigate to='/about' />
  }
]

App.jsx

import React from 'react'
import { NavLink, useRoutes } from 'react-router-dom'
import routes from './routes/index';

export default function App() {
  
  // useRoutes可以用路由表生成<Routes>...</Routes>结构
  // 根据路由表生成对应的路由规则
  const element = useRoutes(routes)
 
  return (
    <div>
      <div className="row">
        <div className="col-xs-offset-2 col-xs-8">
          <div className="page-header">
            <h2>React Router Demo</h2>
          </div>
        </div>
      </div>
      <div className="row">
        <div className="col-xs-2 col-xs-offset-2">
          <div className="list-group">
            {/* 路由链接 */}
            <NavLink className='list-group-item' to="/about">About</NavLink>
            <NavLink className='list-group-item' to="/home">Home</NavLink>
          </div>
        </div>
        <div className="col-xs-6">
          <div className="panel">
            <div className="panel-body">
              {/* 注册路由 */}
              {element}
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

5. 嵌套路由Outlet

作用

如图,News组件和Message组件是Home的子组件

将二级路由放在children属性中注册:

...
{
    path: '/home',
    element: <Home />,
    children: [
      {
        path: 'news',
        element: <News />
      },
      {
        path: 'message',
        element: <Message />
      }
    ]
  },
...

Home.jsx

import React from 'react'
import { NavLink, Outlet } from 'react-router-dom';

export default function Home() {
  return (
    <div>
      <h2>Home组件内容</h2>
      <div>
        <ul className="nav nav-tabs">
          <li>
            <NavLink className="list-group-item" to="news">News</NavLink>
          </li>
          <li>
            <NavLink className="list-group-item" to="message">Message</NavLink>
          </li>
        </ul>
        {/* 指定路由组件呈现的位置 */}
        <Outlet />
      </div>
    </div>
  )
}
举报

相关推荐

0 条评论