React-router 最佳实践

news2024/11/25 6:38:28

使用的是 BrowserRouterRoutes 和 Route,这是 react-router-dom v5 和 v6 都支持的 API。这种方式的优点是路由配置和应用的其它部分是紧密集成的,这使得路由配置更加直观和易于理解 

// router/index.js
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from '../components/Home';
import About from '../components/About';
import User from '../components/User';
import UserDetails from '../components/UserDetails';

function AppRouter() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/user" element={<User />}>
          <Route path=":id" element={<UserDetails />} />
        </Route>
        {/* 添加更多的 Route 组件以定义更多的路由 */}
      </Routes>
    </Router>
  );
}

export default AppRouter;
// App.js
import AppRouter from './router';

function App() {
  return <AppRouter />;
}

export default App;

react-router-dom 获取 params 和 query

import { useParams, useSearchParams } from 'react-router-dom';

function SomeComponent() {
  // 获取路径参数
  const params = useParams();
  const userId = params.id;

  // 获取查询参数
  const [searchParams] = useSearchParams();
  const someQuery = searchParams.get('someQuery');

  // ...
}

注意,setSearchParams 函数会替换所有的查询参数,如果你只想修改某个查询参数,你需要先获取当前的查询参数,然后修改它,然后再调用 setSearchParams。例如:

const [searchParams, setSearchParams] = useSearchParams();
const newSearchParams = new URLSearchParams(searchParams.toString());
newSearchParams.set('someParam', 'newValue');
setSearchParams(newSearchParams);

只有 someParam 参数会被修改,其它的查询参数会保持不变

react-router-dom  v5 vs v6 

// router/index.js
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from '../components/Home';
import About from '../components/About';
import User from '../components/User';
import UserDetails from '../components/UserDetails';

function AppRouter() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/user" element={<User />}>
          <Route path=":id" element={<UserDetails />} />
        </Route>
        {/* 添加更多的 Route 组件以定义更多的路由 */}
      </Routes>
    </Router>
  );
}

export default AppRouter;




v5 
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const Home = () => <h1>Home</h1>;
const About = () => <h1>About</h1>;
const User = () => <h1>User</h1>;
const UserSettings = () => <h1>User Settings</h1>;

const App = () => (
  <Router>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <Route path="/user" component={User}>
        <Route path="/user/settings" component={UserSettings} />
      </Route>
    </Switch>
  </Router>
);

export default App;

outlet

Outlet 组件被用来渲染子路由。当你在一个路由组件中包含一个 Outlet 组件时,它会自动渲染与当前 URL 匹配的子路由。

import { BrowserRouter as Router, Routes, Route, Outlet } from 'react-router-dom';

const Home = () => <h1>Home</h1>;
const About = () => <h1>About</h1>;
const User = () => (
  <div>
    <h1>User</h1>
    <Outlet />  {/* 子路由将会在这里被渲染 */}
  </div>
);
const UserDetails = () => <h1>User Details</h1>;

const App = () => (
  <Router>
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      <Route path="/user" element={<User />}>
        <Route path=":id" element={<UserDetails />} />
      </Route>
    </Routes>
  </Router>
);

export default App;
    多个子路由但是不在一个页面

如果你有多个子路由,但它们不应该在同一个页面上同时渲染,你可以使用 Routes 组件来包裹这些子路由。Routes 组件会渲染与当前 URL 匹配的第一个 Route 组件

import { BrowserRouter as Router, Routes, Route, Outlet } from 'react-router-dom';

const User = () => (
  <div>
    <h1>User</h1>
    <Outlet />  {/* 子路由将会在这里被渲染 */}
  </div>
);

const UserDetails = () => <h1>User Details</h1>;
const UserSettings = () => <h1>User Settings</h1>;

const App = () => (
  <Router>
    <Routes>
      <Route path="/user" element={<User />}>
        // 可省 <Routes>
          <Route path="details" element={<UserDetails />} />
          <Route path="settings" element={<UserSettings />} />
        // </Routes>
      </Route>
    </Routes>
  </Router>
);

export default App;

当你访问 /user/details 时,只有第一个匹配的子路由(UserDetails)
会被渲染在 Outlet 中。尽管你定义了两个与 /user/details 匹配的子路由,
但是 react-router-dom v6 只会渲染第一个匹配的 Route。

因此,无论你访问 /user/details,Outlet 都只会渲染 UserDetails 组件,
而不会渲染 UserSettings 组件。

这是因为 react-router-dom v6 的设计原则之一是:每个 URL 应该对应一个唯一的视图。
如果有多个 Route 与同一个 URL 匹配,那么只有第一个 Route 会被渲染。

你使用了嵌套的 Routes 组件来定义子路由,但这并不会改变路由的行为。
无论你是否使用嵌套的 Routes,react-router-dom 都会渲染与当前 URL
 匹配的第一个 Route 组件。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1689403.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用 Docker 部署 Jenkins 并设置初始管理员密码

使用 Docker 部署 Jenkins 并设置初始管理员密码 每一次开始&#xff0c;我都特别的认真与胆怯&#xff0c;是因为我期待结局&#xff0c;也能够不会那么粗糙&#xff0c;不会让我失望&#xff0c;所以&#xff0c;就多了些思考&#xff0c;多了些拘束&#xff0c;所以&#xf…

基于YOLO系列算法(YOLOv5、YOLOv6、YOLOv8以及YOLOv9)和Streamlit框架的行人头盔检测系统

摘要 本文基于最新的基于深度学习的目标检测算法 (YOLOv5、YOLOv6、YOLOv8)以及YOLOv9) 对头盔数据集进行训练与验证&#xff0c;得到了最好的模型权重文件。使用Streamlit框架来搭建交互式Web应用界面&#xff0c;可以在网页端实现模型对图像、视频和实时摄像头的目标检测功能…

Error:(6, 43) java: 程序包org.springframework.data.redis.core不存在

目录 一、在做SpringBoot整合Redis的项目时&#xff0c;报错&#xff1a; 二、尝试 三、解决办法 一、在做SpringBoot整合Redis的项目时&#xff0c;报错&#xff1a; 二、尝试 给依赖加版本号&#xff0c;并且把版本换了个遍&#xff0c;也不行&#xff0c;也去update过ma…

基于springboot+vue的在线考试系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

web自动化之PO模式

PO模式 1、为什么需要PO思想&#xff1f; 首先我们观察和思考一下&#xff0c;目前我们写的作业脚本的问题&#xff1a; 元素定位和操作动 作写到一起了&#xff0c;这就就会用导致一个问题&#xff1a; UI的页面元素比较容易变化的&#xff0c;所以元素定位和脚本操作写到一…

【Sync FIFO介绍及基于Verilog的实现】

Sync FIFO介绍及实现 1 Intro2 Achieve2.1 DFD2.2 Intf2.3 Module 本篇博客介绍无论是编码过程中经常用到的逻辑–FIFO&#xff1b;该FIFO是基于单时钟下的同步FIFO&#xff1b; FiFO分类&#xff1a;同步FiFO VS 异步FiFO&#xff1b; 1 Intro FIFO可以自己实现&#xff0c;但…

如何安全地进行隔离网数据导出,提升文件流转效率?

隔离网&#xff08;也称为隔离区或DMZ&#xff0c;即Demilitarized Zone&#xff09;是一种网络安全措施&#xff0c;用于将内部网络与外部网络&#xff08;如互联网&#xff09;隔离开来&#xff0c;以减少安全风险。隔离网数据导出通常需要采取一些特殊的安全措施来确保数据的…

pod介绍之 容器分类与重启策略

目录 一 pod 基础概念介绍 1&#xff0c;pod 是什么 2&#xff0c;Pod使用方式 3&#xff0c;如何解决一个pod 多容器通信 4&#xff0c;pod 组成 5&#xff0c; k8s 中的 pod 二 pause容器 1&#xff0c;pause容器 是什么 2&#xff0c;pause容器作用 3&#xff…

【嵌入式Linux】Cmake、makefile、Cmakelist

记录嵌入式 linux环境下的编译方式 测试之前确保你的 Ubuntu 机器上安装了Gcc和cmake 1. 编译有以下几种方式 在 Linux系统下&#xff0c;编译一个 .c文件可以有以下几种方式&#xff1a; 直接用 Gcc 编译器编译为可执行文件编写Makefile文件&#xff0c;使用 make 指令&…

[LEECODE每日一题]找出最具竞争力的子序列

好久没有更新CSDN了,这段时间学业压力比较忙所以没有时间写,今天有时间来看看LEECODE的每日一题,碰巧刷到了这样一道题; 题目给的很清楚,既输入一个序列要求给定一个子序列长度,让其输出为一个最有"竞争力"的序列,说白了就是在所有子序列比较中,处于靠前位置的元素要…

Kafka之【生产消息】

消息&#xff08;Record&#xff09; 在kafka中传递的数据我们称之为消息&#xff08;message&#xff09;或记录(record)&#xff0c;所以Kafka发送数据前&#xff0c;需要将待发送的数据封装为指定的数据模型&#xff1a; 相关属性必须在构建数据模型时指定&#xff0c;其中…

第2天 搭建安全拓展_小迪网络安全笔记

1.常见搭建平台脚本使用: 例如 phpstudy IIS Nginx(俗称中间件): 什么是中间件: 中间件是介于应用系统和系统软件之间的一类软件&#xff0c;它使用系统软件所提供的基础服务&#xff08;功能&#xff09;&#xff0c;衔接网络上应用系统的各个部分或不同的应用&#…

论文阅读--ViLD

现在的目标检测数据集&#xff0c;标注的类别都很有限&#xff0c;如图中的base categories&#xff0c;只能检测出toy而不能检测出细分类别&#xff0c;能不能在现有数据集的基础上&#xff0c;不额外打标注&#xff0c;就能直接检测细分物体&#xff1f; &#xff08;a&#…

订餐系统总结、

应用层&#xff1a; SpringBoot:快速构建Spring项目&#xff0c;采用“约定大于配置”的思想&#xff0c;简化Spring项目的配置开发。 SpringMvc&#xff1a;Spring框架的一个模块&#xff0c;springmvc和spring无需通过中间整合层进行整合&#xff0c;可以无缝集成。 Sprin…

深度学习之Python+OpenCV+Tensorflow实时人体检测和计数

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 深度学习之PythonOpenCVTensorflow实时人体检测和计数项目简介 一、项目背景与意义 随着科技的不断发展&#xff…

Spring 事件监听

参考&#xff1a;Spring事件监听流程分析【源码浅析】_private void processbean(final string beanname, fi-CSDN博客 一、简介 Spring早期通过实现ApplicationListener接口定义监听事件&#xff0c;Spring 4.2开始通过EventListener注解实现监听事件 FunctionalInterface p…

Excel插入多行VBA实现

我们还可以利用 VBA&#xff08;Visual Basic for Applications&#xff09;宏语言&#xff0c;在 Excel 中写一个 VBA 宏来自动插入多行数据。这种方法可以方便我们自定义需要插入的行数和插入位置。下面是编写 VBA 宏的步骤&#xff1a; 1、按下Alt F11快捷键&#xff0c;打…

python文件名通常以什么结尾

python文件后缀一般有两个&#xff0c;分别是.py和.pyw。视窗用 python.exe 运行 .py&#xff0c;用 pythonw.exe 运行 .pyw 。 这纯粹是因为安装视窗版Python时&#xff0c;扩展名 .py 自动被登记为用 python.exe 运行的文件&#xff0c;而 .pyw 则被登记为用 pythonw.exe 运…

c++ - vector容器常用接口模拟实现

文章目录 一、成员变量二、常用迭代器接口模拟实现三、一些常用接口模拟四、默认成员函数五、功能测试 一、成员变量 我们通过在堆上申请一个数组空间来进行储存数据&#xff0c;我们的成员变量是三个指针变量&#xff0c;分别指向第一个位置、最后储存有效位置的下一个位置以…

OpenMV学习笔记1——IDE安装与起步

目录 一、OpenMV IDE下载 二、OpenMV界面 三、Hello World&#xff01; 四、将代码烧录到OpenMV实现脱机运行 五、插SD卡&#xff08;为什么买的时候没送&#xff1f;&#xff09; 一、OpenMV IDE下载 浏览器搜索OpenMV官网&#xff0c;进入后点击“立即下载”&#xff0…