【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)

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

相关推荐
朱小勇本勇17 分钟前
Python-Pdf转Markdown
前端·python·pdf
小满zs1 小时前
React第二十章(useMemo)
前端·javascript·react.js
赵大仁1 小时前
Tailwind CSS:现代 CSS 框架的优雅之选
前端·javascript·vue.js·前端框架·css3·html5·scss
GIS学姐嘉欣1 小时前
25考研希望渺茫,工作 VS 二战,怎么选?
前端·学习·考研·gis
二川bro1 小时前
图片叠加拖拽对比展示效果实现——Vue版
前端·vue.js
russle1 小时前
android app构建时排除指定类
android·前端·chrome
愚愚是个大笨蛋1 小时前
自定义VUE指定,实现鼠标悬停显示提示面板,离开元素或面板后面板消失
前端·javascript·vue.js
CSNMD1 小时前
VueRouter之HelloWorld
前端·javascript·vue.js
Smileyqp沛沛1 小时前
gz、zip等压缩文件postman成功下载但是前端项目中下载解压失败
前端·测试工具·postman
xcLeigh1 小时前
HTML5实现好看的新年春节元旦网站源码
前端·html·html5