二十三、React Router 6

郁子大约 4 分钟约 1189 字笔记React18React Router 6李立超

(一)React Router 6 简介

1.Routes

  • v6 新组件
  • 作用和 v5 的 Switch 类似,用于 Route 的容器
  • Route 只有一个会被匹配,且必须定义 Routes

2.Route

  • componentrenderchildren 都变了
  • 需要通过 element 来指定要挂载的组件

3. src/index.js

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter as Router } from "react-router-dom";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <Router>
    <App />
  </Router>,
);

4. src/App.js

import React from "react";
import { Routes, Route } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import Menu from "./components/Menu";

const App = () => {
  return (
    <div>
      <h1>App</h1>
      <Menu />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
      </Routes>
    </div>
  );
};

export default App;

5. src/components/Home.jsx

import React from "react";

const Home = () => {
  return (
    <div>
      <h2>主页</h2>
      <p>主页的内容真精彩</p>
    </div>
  );
};

export default Home;

6. src/components/About.jsx

import React from "react";

const About = () => {
  return (
    <div>
      <h2>关于我们,其实是三兄弟</h2>
      <ul>
        <li>刘备</li>
        <li>关羽</li>
        <li>张飞</li>
      </ul>
    </div>
  );
};

export default About;

7. src/components/Menu.jsx

import React from "react";
import { Link } from "react-router-dom";

const Menu = () => {
  return (
    <div>
      <ul>
        <li>
          <Link to="/">主页</Link>
        </li>
        <li>
          <Link to="/about">关于</Link>
        </li>
      </ul>
    </div>
  );
};

export default Menu;

(二)参数和钩子

1. src/App.js

import React from "react";
import { Routes, Route } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import Menu from "./components/Menu";
import Student from "./components/Student";

const App = () => {
  return (
    <div>
      <h1>App</h1>
      <Menu />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="student/:id" element={<Student />} />
      </Routes>
    </div>
  );
};

export default App;

2. src/components/Student.jsx

import React from "react";
import { useLocation, useParams, useMatch, useNavigate } from "react-router-dom";

const STU_DATA = [
  {
    id: 1,
    name: "aaa",
  },
  {
    id: 2,
    name: "bbb",
  },
  {
    id: 3,
    name: "ccc",
  },
  {
    id: 4,
    name: "ddd",
  },
];

const Student = () => {
  // 可以使用useParams()获取参数
  const { id } = useParams();
  const stu = STU_DATA.find((item) => item.id === +id);

  // 获取当前地址信息
  const location = useLocation();
  console.log(location);

  // 用于检查当前url是否匹配某个路由【匹配返回对象,否则返回null】
  const match1 = useMatch("/about");
  const match2 = useMatch("/student/:id");
  console.log(match1, match2);

  // 获取用于跳转页面的函数,作用同history
  const navigate = useNavigate();
  const clickHandler = () => {
    // navigate("/about"); // push跳转
    navigate("/about", {
      replace: true,
    }); // replace跳转
  };

  return (
    <div>
      {/* <h2>1---fff</h2> */}
      <h2>
        {stu.id}---{stu.name}
      </h2>
      <button onClick={clickHandler}>点我一下</button>
    </div>
  );
};

export default Student;

(三)嵌套路由和 Outlet

1.路由嵌套实现方式

1)关闭严格匹配

  • 不推荐
<Route path="about/*" element={<About />} />

2)使用 Route

  • 需要在显示的组件中定义 Outlet
<Route path="about" element={<About />}>
  <Route path="hello" element={<Hello />}></Route>
</Route>

2.嵌套路由组件的映射方式

1)通过子路由对 Hello 组件进行映射 /about/hello

<Routes>
  <Route path={"hello"} element={<Hello />} />
</Routes>

2)Outlet

  • 用于表示嵌套路由中的组件
  • 当嵌套路由中的路径匹配成功了, Outlet 则表示嵌套路由中的组件
  • 当嵌套路由中的路径匹配失败了, Outlet 就什么也不是
<Outlet />

3. src/App.js

import React from "react";
import { Routes, Route } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import Menu from "./components/Menu";
import Hello from "./components/Hello";

const App = () => {
  return (
    <div>
      <h1>App</h1>
      <Menu />
      <Routes>
        <Route path="/" element={<Home />} />

        {/* <Route path="about/*" element={<About />} /> */}

        <Route path="about" element={<About />}>
          <Route path="hello" element={<Hello />}></Route>
        </Route>
      </Routes>
    </div>
  );
};

export default App;

4. src/components/About.jsx

import React from "react";
import { Routes, Route, Outlet } from "react-router-dom";
import Hello from "./Hello";

const About = () => {
  return (
    <div>
      <h2>关于我们,其实是三兄弟</h2>
      <ul>
        <li>刘备</li>
        <li>关羽</li>
        <li>张飞</li>
      </ul>
      <Hello />

      {/* <Routes>
        <Route path={"hello"} element={<Hello />} />
      </Routes> */}

      <Outlet />
    </div>
  );
};

export default About;

5. src/components/Hello.jsx

import React from "react";

const Hello = () => {
  return (
    <div>
      <h2>Hello</h2>
    </div>
  );
};

export default Hello;

(四)Navigate 组件

  • 用来跳转到指定的位置,类似 v5 的 Redirect 组件
  • 默认使用 push 跳转
  • replace 设置为 replace 跳转

1. src/App.js

import React from "react";
import { Routes, Route } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import Menu from "./components/Menu";

const App = () => {
  return (
    <div>
      <h1>App</h1>
      <Menu />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
      </Routes>
    </div>
  );
};

export default App;

2. src/components/About.jsx

import React from "react";
import { Navigate } from "react-router-dom";

const About = () => {
  return (
    <div>
      <Navigate to="/student/1" replace />

      <h2>关于我们,其实是三兄弟</h2>
      <ul>
        <li>刘备</li>
        <li>关羽</li>
        <li>张飞</li>
      </ul>
    </div>
  );
};

export default About;

1. src/App.js

import React from "react";
import { Routes, Route } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import Menu from "./components/Menu";
import Student from "./components/Student";

const App = () => {
  return (
    <div>
      <h1>App</h1>
      <Menu />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="student/:id" element={<Student />} />
      </Routes>
    </div>
  );
};

export default App;

2. src/components/Menu.jsx

import React from "react";
import { Link, NavLink } from "react-router-dom";

const Menu = () => {
  return (
    <div>
      <ul>
        <li>
          <Link to="/">主页</Link>
        </li>
        <li>
          <Link to="/about">关于</Link>
        </li>
        <li>
          <NavLink
            style={({ isActive }) => {
              return isActive
                ? {
                    backgroundColor: "yellow",
                  }
                : null;
            }}
            to="/student/2"
          >
            学生
          </NavLink>
        </li>
      </ul>
    </div>
  );
};

export default Menu;

3. src/components/Studnet.jsx

import React from "react";
import { useParams } from "react-router-dom";

const STU_DATA = [
  {
    id: 1,
    name: "aaa",
  },
  {
    id: 2,
    name: "bbb",
  },
  {
    id: 3,
    name: "ccc",
  },
  {
    id: 4,
    name: "ddd",
  },
];

const Student = () => {
  // 可以使用useParams()获取参数
  const { id } = useParams();
  const stu = STU_DATA.find((item) => item.id === +id);

  return (
    <div>
      {/* <h2>1---fff</h2> */}
      <h2>
        {stu.id}---{stu.name}
      </h2>
    </div>
  );
};

export default Student;
上次编辑于: