react-router 路由

安装
npm

npm install react-router-dom@6 -S

yarn

yarn add react-router-dom@6 -S
设置
要让 React Router 在您的应用程序中工作,您需要在元素树的根部或附近渲染一个路由器元素。
根据您的应用程序运行的位置,我们提供了几种不同的路由器。

<BrowserRouter>或者<HashRouter>应该在 Web 浏览器中运行时使用(您选择哪一个取决于您喜欢或需要的 URL 样式)
<NativeRouter>应该在React Native应用程序中使用。

API 参考

  • BrowserRouter

<BrowserRouter>使用干净的 URL 将当前位置存储在浏览器的地址栏中,并使用浏览器的内置历史堆栈进行导航。

import * as React from "react";
import * as ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";

ReactDOM.render(
  <BrowserRouter>
    {/* The rest of your app goes here */}
  </BrowserRouter>,
  root
);
  • NavLink

<NavLink>是一种特殊的类型,<Link>它知道它是否“活跃”。这在构建导航菜单(如面包屑或一组选项卡)时很有用,
以根据<NavLink>组件的活动状态自定义组件的内容,这对于更改内部元素的样式特别有用。

<NavLink to="/" >
  Home
</NavLink>
  • Navigate

<Navigate>元件改变时,它呈现的当前位置。它是一个围绕 的组件包装器useNavigate,并接受与 props 相同的所有参数。

replace: 重定向

<Navigate to="/dashboard" replace={true} />
  • Outlet

<Outlet>应该在父路由元素中使用An来呈现其子路由元素。这允许在渲染子路由时显示嵌套 UI。
如果父路由完全匹配,它将渲染子索引路由,如果没有索引路由,则不渲染。

<Outlet />
  • useLocation

这个钩子返回当前location对象。如果您想在当前位置更改时执行一些副作用,这可能很有用。

import * as React from 'react';
import { useLocation } from 'react-router-dom';

function App() {
  let location = useLocation();

  React.useEffect(() => {
    ga('send', 'pageview');
  }, [location]);

  return (
    // ...
  );
}
  • useSearchParams

该useSearchParams钩子用于读取和修改当前位置的 URL 中的查询字符串。
useSearchParams返回一个包含两个值的数组:当前位置的搜索参数和一个可用于更新它们的函数。

import * as React from "react";
import { useSearchParams } from "react-router-dom";

function App() {
  let [searchParams, setSearchParams] = useSearchParams();

  function handleSubmit(event) {
    event.preventDefault();
    let params = serializeFormQuery(event.target);
    setSearchParams(params);
  }

  return (
    <div>
      <form onSubmit={handleSubmit}>{/* ... */}</form>
    </div>
  );
}
  • useParams

该useParams钩子从当前 URL 返回一个由<Route path>. 子路由继承父路由的所有参数。

import * as React from 'react';
import { Routes, Route, useParams } from 'react-router-dom';

function ProfilePage() {
  // 从URL获取用户ID参数。
  let { userId } = useParams();
  // ...
}

function App() {
  return (
    <Routes>
      <Route path="users">
        <Route path=":userId" element={<ProfilePage />} />
        <Route path="me" element={...} />
      </Route>
    </Routes>
  );
}
  • useNavigate

该useNavigate钩子返回的功能,可以让一个表单提交后您导航程序。

import { useNavigate } from "react-router-dom";

function SignupForm() {
  let navigate = useNavigate();

  async function handleSubmit(event) {
    event.preventDefault();
    await submitForm(event.target);
    navigate("../success", { replace: true });
  }

  return <form onSubmit={handleSubmit}>{/* ... */}</form>;
}

入口文件


App.js

import './App.css';
import {BrowserRouter, useLocation  } from 'react-router-dom'
import RouterList from './routers/index';
import React from 'react'
import Tab from './components/common/tabbar'

function Breadcrumb() {
  // 获取路由地址
  const location = useLocation();
  var showTabs = true
  if(location.pathname == '/' || location.pathname == '/user/base/index' || location.pathname == '/contact/contact/index'){
    showTabs = true;
  } else{
    showTabs = false;
  }
  return (<div>{showTabs ?  <Tab /> : ''}</div>);
}

class App extends React.Component {
  render() {
    return (
      <BrowserRouter>
        <RouterList/>
        <Breadcrumb/>
      </BrowserRouter>
    );
  }

}

export default App;

路由总入口文件

src/routers/index.js


import React from 'react'
import {Routes, Route, Outlet} from 'react-router-dom'
import AuthRouter from './auth'
import Home from '@/components/home.js'

// 引入每个目录下面的index.js文件
const ModulesFile = require.context('./',true,/index.js$/)

// 总路由集合
const RouterMap = []

//对引入的文件进行循环
ModulesFile.keys().reduce((modules, modulePath) => {

  // 路由模块名称   文件夹/index  user/index
  const ModuleName = modulePath.replace(/^.\/(.*)\.js/,'$1')

  //不包含当前index.js 文件
  if(ModuleName !== 'index')
  {
    //路由列表
    const ModuleList = ModulesFile(modulePath)

    //追加到数组
    RouterMap.push(...ModuleList.default)
  }

  return RouterMap
}, {})


class RouterList extends React.Component{
  constructor(props)
  {
    super(props)

    this.state = {}
  }

  render()
  {
    return (
      <>
        <Routes>
          {/* 默认首页 */}
          <Route path="/" element={<Home />}></Route>

          <Route path="/" element={<><Outlet /></>}>
            {
              RouterMap.map((item, index) => {
                return (
                  <Route key={index} path={item.path} element={<AuthRouter auth={item.auth} component={<item.component />}></AuthRouter>}>
                    {item.children &&
                      item.children.map((son, idx) => <Route key={idx} path={son.path} element={<AuthRouter auth={son.auth} component={<son.component />}></AuthRouter>}></Route>)
                    }
                  </Route>
                )
              })
            }
          </Route>
        </Routes>
      </>
    )
  }
}

export default RouterList

每个独立路由模块下面的入口文件index.js


src/routers/user/index.js


import { Outlet } from 'react-router-dom'

// 引入当前目录下面的所有文件
const ModulesFile = require.context('./',true,/.js$/)

const RouterMap = []

ModulesFile.keys().reduce((modules, modulePath) => {
  // 路由模块名称
  const ModuleName = modulePath.replace(/^.\/(.*)\.js/,'$1')

  //不包含当前index.js 文件
  if(ModuleName !== 'index')
  {
    //路由列表(数组)
    const ModuleList = ModulesFile(modulePath)

    //追加到数组
    RouterMap.push(...ModuleList.default)
  }

  return RouterMap
},{})

//默认父组件 可以自己定义
const layout = () => {
  return (
    <>
      <Outlet />
    </>
  )
}

const RouterList = [
  {
    path: '/user',
    component: layout,
    children: RouterMap,
  }
]

export default RouterList


独立模块的路由文件


src/routers/user/base.js

import profile from "@/components/user/profile"
import index from "@/components/user/index"
import login from "@/components/user/login"

const base = [
    {
        path: "base/index",
        name: 'baseindex',
        component: index,
        auth: true
    },
    {
        path: "base/profile",
        name: 'profile',
        component: profile,
        auth: true
    },
    {
        path: "base/login",
        name: 'login',
        component: login,
    },
]
export default base
powered by GitbookEdit Time: 2023-04-08 10:28:32