【React】React Router

简介

React Router 是一款适用于 React 的多策略路由管理库。

文档

react router V6文档:

reactrouter.cn/docs/gettin...

安装

css 复制代码
npm install react-router-dom@6

声明式导航

初始化路由

react-router-dom 中导出 BrowserRouter ,使用 BrowserRouter 包裹App组件

javascript 复制代码
// index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
// 引入路由模块
import { BrowserRouter } from 'react-router-dom';
import App from './App';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

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

配置路由

修改 App.tsx ,添加路由配置

javascript 复制代码
import React, { useEffect, useRef, useState } from 'react';
import { Link, Route, Routes } from 'react-router-dom';
const Home = () => {
  return (
    <div>
      <nav>
        <Link to="/about">About</Link>
      </nav>
      <main>
        <h2>Home</h2>
      </main>
    </div>
  )
}

const About = () => {
  return (
    <div>
      <nav>
        <Link to="/">Home</Link>
      </nav>
      <main>
        <h2>About</h2>
      </main>
    </div>
  )
}

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

export default App;

添加链接

使用 Link 添加链接,可以更改URL而不会导致页面重新加载,与 Route 配合可以实现路由跳转

javascript 复制代码
import React, { useEffect, useRef, useState } from 'react';
import { Link, Route, Routes } from 'react-router-dom';

function App() {
  return (
    <div className="App">
     <Link to="/">Home</Link>
     <Link to="/about">About</Link>
    </div>
  );
}

export default App;

嵌套路由

Route 之间可以进行嵌套,父路内容在子组件之间进行共享,通过 Outlet 承接子组件内容。

javascript 复制代码
// Home/index.tsx
const Home = () => {
  return (
    <div>
      <h2>Home</h2>
    </div>
  )
}

export default Home;

// About/index.tsx
const About = () => {
  return (
    <div>
      <h2>About</h2>
    </div>
  )
}
export default About;
javascript 复制代码
// App.tsx
import React, { useEffect, useRef, useState } from 'react';
import './App.css';
import { Link, Outlet } from 'react-router-dom';

function App() {
  return (
    <div className="App">
      <nav>
        <h2>App</h2>
        <Link to="/home">Home</Link> | 
        <Link to="/about">About</Link>
      </nav>
      {/* 承接子路由内容 */}
      <Outlet />
    </div>
  );
}

export default App;
javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import App from './App';
import Home from './pages/Home';
import About from './pages/About';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

root.render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<App />}>
        <Route path="home" element={<Home />} />
        <Route path="about" element={<About />} />
      </Route>
    </Routes>
  </BrowserRouter>
);

无匹配路由

当路由没有匹配的时候会出现页面白屏的情况,为了处理这种情况可以配置 "无匹配" 路由,通常也叫做 "兜底路由"。

javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import Home from './pages/Home';
import About from './pages/About';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

// 无匹配页面
const NoMatch = () => {
  return (
    <div>
      <h2>Nothing to see here!</h2>
    </div>
  );
}

root.render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<App />}>
        <Route path="home" element={<Home />} />
        <Route path="about" element={<About />} />
        {/* 无匹配路由 */}
        <Route path="*" element={<NoMatch />} />
      </Route>
    </Routes>
  </BrowserRouter>
);

动态链接

使用 NavLink 代替 Link 将链接显示为用户正在查看的状态。

javascript 复制代码
// App.css
.hightStyle {
  color: red;
}
.normalStyle {
  color: black;
}

// App.tsx
import React, { useEffect, useRef, useState } from 'react';
import './App.css';
import { Link, NavLink, Outlet } from 'react-router-dom';

function App() {
  const navStyle = ({ isActive }: { isActive: boolean }) => {
    return {
      color: isActive ? 'red' : 'black'
    }
  }
  return (
    <div className="App">
      <nav>
        <h2>App</h2>
        <NavLink style={ navStyle } to="/home">Home</NavLink> | 
        <NavLink style={ navStyle } to="/about">About</NavLink>| 
        <NavLink className={ ({ isActive }) => isActive ? 'hightStyle' : 'normalStyle' } to="/home">Home</NavLink> | 
        <NavLink className={ ({ isActive }) => isActive ? 'hightStyle' : 'normalStyle' } to="/about">About</NavLink>
      </nav>
      {/* 承接子路由内容 */}
      <Outlet />
    </div>
  );
}

export default App;

动态路由

javascript 复制代码
import React, { useEffect, useRef, useState } from 'react';
import './App.css';
import { Link, NavLink, Outlet, useParams, useRoutes } from 'react-router-dom';
const Home = () => <h1>Home Page</h1>;
const About = () => <h1>About Page</h1>;
const User = () => {
  const params = useParams();
  console.log('params',params)
  return <h1>User Page</h1>
};
// 路由配置函数
const routes = [
  { path: '/home', element: <Home /> },
  { path: '/about', element: <About /> },
  {
    path: '/user/:id',
    element: <User />,
  },
];
function App() {
  // 创建动态路由
  const element = useRoutes(routes);
  
  return (
    <div className="App">
      <nav>
        <h2>App Layout</h2>
        {element}
      </nav>
      <Outlet />
    </div>
  );
}
export default App;

路由参数

获取路由跳转路径参数

javascript 复制代码
<Routes>
  <Route path="/" element={<App />}>
    <Route path="home" element={<Home />} />
    <Route path="about" element={<About />}>
      {/* path传参 */}
      <Route path=":id" element={<About />} />
    </Route>        
    {/* 无匹配路由 */}
    <Route path="*" element={<NoMatch />} />
  </Route>
</Routes>

// 配置链接
<Link to="/about/11">about</Link> | 
<NavLink to="/about/11">about</NavLink> | 

// 获取参数
const usePrams = useParams();
console.log(usePrams); 

获取路由跳转params参数

javascript 复制代码
import { Link, NavLink, useNavigate, useLocation } from "react-router-dom";

// Home.tsx
const Home = () => {
  const navigate = useNavigate();
  
  return (
    <div>
      <h2>Home</h2>
      <Link to="/about" state={{ name: "hello" }}>about</Link> | 
      <NavLink to="/about" state={{ name: "hello" }}>about</NavLink>
    </div>
  )
}

// About.tsx
const About = () => {
  // 获取params
  const params = useLocation();
  console.log(params);
  return (
    <div>
      <h2>About</h2>
    </div>
  )
}

获取URL后?拼接的参数

javascript 复制代码
import { useSearchParams } from "react-router-dom";
const Home = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  return (
    <div>
      <h2>Home</h2>
      <input type="text" value={searchParams.get("name") || ""} onChange={(e) => setSearchParams({ name: e.target.value })}  />
    </div>
  )
}

export default Home;

通过 useSearchParams 读取和操作拼接在路由后的搜索参数

  • useSearchParams 返回一个 URLSearchParamssetSearchParams()
  • setSearchParams()?name=... 搜索参数放在 URL 中并重新渲染路由器

编程式导航

路由跳转

编程式导航使用 useNavigate 进行路由跳转

javascript 复制代码
import { Link, NavLink, useNavigate, useLocation } from "react-router-dom";
// Home.tsx
const Home = () => {
  // 使用导航
  const navigate = useNavigate();
  
  return (
    <div>
      <h2>Home</h2>
      <button onClick={() => {
        // 跳转about
        navigate('/about')
      }}>push to About</button>
    </div>
  )
}

获取参数

编程式导航使用 useNavigate 进行路由跳转传参,传递的参数放在 state

javascript 复制代码
import { Link, NavLink, useNavigate, useLocation } from "react-router-dom";
// Home.tsx
const Home = () => {
  const navigate = useNavigate();
  
  return (
    <div>
      <h2>Home</h2>
      <button onClick={() => {
        navigate('/about', { state: { name: "hello" } })
      }}>push to About</button>
    </div>
  )
}

获取参数

javascript 复制代码
// About.tsx
import { Link, NavLink, useNavigate, useLocation } from "react-router-dom";

const About = () => {
  // 获取params
  const params = useLocation();
  console.log(params);
  return (
    <div>
      <h2>About</h2>
    </div>
  )

友情提示

见原文:【React】React Router)

本文同步自微信公众号 "程序员小溪" ,这里只是同步,想看及时消息请移步我的公众号,不定时更新我的学习经验。

相关推荐
青红光硫化黑15 分钟前
React基础之React.memo
前端·javascript·react.js
大麦大麦19 分钟前
深入剖析 Sass:从基础到进阶的 CSS 预处理器应用指南
开发语言·前端·css·面试·rust·uni-app·sass
m0_616188492 小时前
Vue3 中 Computed 用法
前端·javascript·vue.js
六个点2 小时前
图片懒加载与预加载的实现
前端·javascript·面试
Patrick_Wilson2 小时前
🔥【全网首篇】30分钟带你从0到1搭建基于Lynx的跨端开发环境
前端·react.js·前端框架
Moment2 小时前
前端 社招 面筋分享:前端两年都问些啥 ❓️❓️❓️
前端·javascript·面试
Moment2 小时前
一坤时学习 TS 中的装饰器,让你写 NestJS 不再手软 😏😏😏
前端·javascript·面试
子洋2 小时前
AnythingLLM + SearXNG 实现私有搜索引擎代理
前端·人工智能·后端
小满zs3 小时前
React第二十九章(css in js)
前端·react.js
古柳_Deserts_X3 小时前
Manus官方发布视频的1小时后就开始陆续有人注册了相关网站域名!原因就在于「新词新站」这4个字
前端·程序员·创业