Skip to content
On this page
🎨 作者:Jacinda 📔 阅读量:

React - Router 6.x

终于开始学习 React 了!!!之前简单的过了一遍 React 的相关语法,写法和 Vue 还是有很大区分度的。最近开始自己写练习项目,把知识点串起来。所以就先从页面和路由入手啦!

这里就先不讲项目搭建了,我目前用的是 Vite + React

这里归纳两种写法:

  • Routes 和 Route 标签
  • 路由封装

写法一: Routes 和 Route 标签

目录结构

src
└── containers
    ├─ layout
    │   └── layout.jsx // 布局
    ├─ home
    │   └── home.jsx // 首页   
    ├─ record
    │   └── record.jsx // 记录(随便写的一个测试页
    ├─
    main.jsx // 入口

main.jsx 文件

javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';

import Layout from './containers/layout/layout.jsx';

import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
    <BrowserRouter>
        <Layout></Layout>
    </BrowserRouter>
);

layout.jsx 文件

在此文件中,添加 RoutesRoute 标签, Navigate 用于重定向

Outlet 相当于 Vue 中的 router-view 标签

因为我想实现,固定顶部导航栏,导航栏下方,通过点击导航中的每一项,在下方显示对应页面的内容

javascript
import React from "react";
import { Routes, Route, Outlet, Navigate } from 'react-router-dom';

import Navbar from "@/components/NavBar/NavBar";
import Home from '@/containers/home/home'
import Record from '@/containers/record/record'

class Layout extends React.Component {
    render() {
        const navList = [
            {
                title: 'Home',
                path: '/home'
            },
            {
                title: 'Record',
                path: '/record'
            },
        ];
        return (
            <div className="wrap">
                <Navbar navList={navList} />
                <Outlet />

                <Routes>
                    <Route path="/" element={<Navigate to="/home" />}></Route>
                    <Route path="/home" element={<Home />}></Route>
                    <Route path="/record" element={<Record />}></Route>
                </Routes>
            </div>
        )
    }
}

export default Layout

写法二: 路由封装

考虑到后期如果页面开始增加,那么就需要在 layout 中,一直写 Route标签。所以就考虑把路由进行封装,所有页面路径体现在 router 文件中也更直观

目录结构

src
└── containers
    ├─ layout
    │   └── layout.jsx // 布局
    ├─ home
    │   └── home.jsx // 首页   
    ├─ record
    │   └── record.jsx // 记录(随便写的一个测试页
    router
    ├─ index.jsx // 路由封装
    App.jsx
    ├─
    main.jsx // 入口

main.jsx 文件

javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';

import App from './App.jsx'

import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
    <BrowserRouter>
        <App />
    </BrowserRouter>
);

app.jsx 文件

javascript
import { Suspense } from 'react';
import { useRoutes } from 'react-router-dom';
import routers from './router';

function App() {
  const element = useRoutes(routers);
  return (
    <div className='App'>
      <Suspense fallback={<>加载中...</>}>
        {element}
      </Suspense>
    </div>
  )
}

export default App

封装好的路由文件

因为使用了 lazy 懒加载,所以上述在 App.jsx 文件中,使用了 Suspense 标签。这两者需要一起使用,否则会显示不了

javascript
import { Navigate } from 'react-router-dom';
import { lazy } from 'react';

/**
 * @name 路由懒加载
*/

const Layout = lazy(() => import('@/containers/layout/layout'));
const Home = lazy(() => import('@/containers/home/home'));
const Record = lazy(() => import('@/containers/record/record'));

/**
 * @name 路由配置 
*/

let routers = [
    {
        path: '/',
        element: <Layout />,
        children: [
            {
                path: '',
                element: <Navigate to="/home" />
            },
            {
                path: 'home',
                element: <Home />
            },
            {
                path: 'record',
                element: <Record />
            },
        ]
    },
];

export default routers

layout.jsx 文件

javascript
import React from "react";
import { Outlet } from 'react-router-dom';

import Navbar from "@/components/NavBar/NavBar";

class Layout extends React.Component {
    render() {
        const navList = [
            {
                title: 'Home',
                path: '/home'
            },
            {
                title: 'Record',
                path: '/record'
            },
        ];
        return (
            <div className="wrap">
                <Navbar navList={navList} />
                <Outlet />
            </div>
        )
    }
}

export default Layout

📖 参考文档