IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React Router(react-router-dom V6 整理) -> 正文阅读

[JavaScript知识库]React Router(react-router-dom V6 整理)

目录

基本用法

在Web应用程序中开启 React Router 功能

配置路由

添加 "不匹配" 路由

使用链接导航

使用嵌套路由

使用活动链接

读取 URL 参数

与 V5 的区别


基本用法

在Web应用程序中开启 React Router 功能

// index.js

import React from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

const container = document.getElementById('root');
const root = createRoot(container);
root.render(
  // 通过在应用入口添加 BrowserRouter 组件开启 React Router 功能
  <BrowserRouter>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </BrowserRouter>
);

注意:web 应用程序中一般使用?BrowserRouter?组件, 还用另一种?HashRouter?组件方式;
这两种方式的区别:

  1. 底层原理不一样:
    BrowserRouter调用的是?H5 history API,低版本兼容性问题;
    HashRouter?使用的是?URL?哈希值;
  2. 地址栏表现形式不一样:
    BrowserRouter的路径:localhost:3000/index
    HashRouter的路径:localhost:3000/#/index
  3. 刷新后对路由?state?参数的影响
    BrowserRouter没有任何影响,因为?state?保存在?history?对象中
    HashRouter刷新后会导致路由?state?参数的丢失

值得注意的是,官方强烈建议不要使用?HashRouter;

配置路由

// App.js

// 导入 Route, Routes 组件
import { Route, Routes } from 'react-router-dom';

function App() {
  return (
    <Routes>
	  {/* 页面默认导航到 Home 组件(页面上显示 Home Compontent) */}
      <Route path='/' element={<Home />} />
	  {/* 在地址输入 http://localhost:3000/about 导航到 About 组件(页面上显示 About Compontent) */}
      <Route path='/about' element={<About />} />
    </Routes>
  );
}

const Home = (props) => {
  return <div>Home Compontent</div>;
}

const About = (props) => {
  return <div>About Compontent</div>;
}

export default App;
 

在以前版本的?React Router?中,必须以某种方式对路由进行排序,以便在多个路由与不明确的?URL?匹配时获得要呈现的正确路由。V6更智能,会选择最具体的匹配;

添加 "不匹配" 路由

// App.js

import { Route, Routes } from 'react-router-dom';

function App() {
  return (
    <Routes>
      <Route path='/' element={<Home />} />
      <Route path='/about' element={<About />} />
      {/* 当没有其他路由与 URL 匹配时,匹配 path='*'的路由 */}
      <Route path='*' element={<NotFount />} />
    </Routes>
  );
}

const Home = (props) => {
  return <div>Home Compontent</div>;
}

const About = (props) => {
  return <div>About Compontent</div>;
}

const NotFount = (props) => {
  return <div>NotFount !!!</div>;
}

export default App;
 

当没有其他路由与 URL 匹配时,才会匹配?path='*'路由。此路由将匹配任何 URL,但优先级最弱,因此路由器仅在没有其他路由匹配时才会选择它;

使用链接导航

// App.js

// 导入 Link 组件
import { Route, Routes, Link } from 'react-router-dom';

function App() {
  return (
    <Routes>
	  {/* 页面默认导航到 Home 组件(渲染 Home 组件, 页面显示 About Compontent 链接) */}
      <Route path='/' element={<Home />} />
      <Route path='/about' element={<About />} />
    </Routes>
  );
}

const Home = (props) => {
  return <div>
    {/* 点击 About Link 链接跳转至 http://localhost:3000/about
        画面显示 About 组件内容(Home Link链接)
      */}
    <Link to='/about'>About Link</Link>
  </div>;
}

const About = (props) => {
  return <div>
    {/* 点击 Home Link 链接跳转至 http://localhost:3000/
        画面显示 Home 组件内容(About Link链接)
      */}
    <Link to='/'>Home Link</Link>
  </div>;
}

export default App;

使用嵌套路由

// App.js

// 导入 Link, Outlet 组件
import { Route, Routes, Link, Outlet } from 'react-router-dom';

function App() {
  return (
    <Routes>
      <Route path='/' element={<Home />} >
        <Route path='about' element={<About />} />
        <Route path='setting' element={<Setting />} />
        {/* 默认子路由
            如果导航栏地址为 http://localhost:3000,此时子路由渲染位置(Outlet)为空白,
            增加以下配置,子路由渲染位置(Outlet)渲染 <List />
         */}
        <Route index element={<List />} />
      </Route>
    </Routes>
  );
}

const Home = (props) => {
  return <>
    <div>
      <Link to='/about'>About Link</Link> | {" "}
      <Link to='/setting'>Setting Link</Link>
    </div>
    <div style={{padding: '20px', margin: '10px', borderTop: '1px solid'}}>
      {/* Outlet 为嵌套子路由的出口,比如:点击 About Link 链接,
          浏览器地址变为 http://localhost:3000/about
          在此渲染路由地址为 /about 的组件(在此显示: About Compontent)
       */}
      <Outlet />
    </div>
  </>;
}

const About = (props) => {
  return <div>
    About Compontent
  </div>;
}

const Setting = (props) => {
  return <div>
    Setting Compontent
  </div>;
}

const List = (props) => {
  return <div>
    List Compontent
  </div>;
}

export default App;

这是?React Router?最强大的功能之一,在实际开发中,大多数 UI 都是一系列嵌套布局,React Router?通过这种嵌套路由的方式实现了一些自动、持久的布局处理;

使用活动链接

// App.js

// 导入 NavLink 组件
import { Route, Routes, NavLink, Outlet } from 'react-router-dom';

function App() {
  return (
    <Routes>
      <Route path='/' element={<Home />} >
        <Route path='about' element={<About />} />
        <Route path='setting' element={<Setting />} />
        <Route index element={<List />} />
      </Route>
    </Routes>
  );
}

const Home = (props) => {
  return <>
    <div>
      {/* <NavLink /> 接收一个style 或者 className 属性
          属性值为一个回调函数,可以通过 isActive 的值判断
          链接是否处于活动状态,从而实现给活动链接节点添加样式的效果
          示例效果:点击哪个链接,目标链接字体变红
       */}
      <NavLink
        style={({ isActive }) => navColor(isActive)}
        to='/about'
      >
        About Link
      </NavLink> | {" "}
      <NavLink
        style={({isActive}) => navColor(isActive)}
        to='/setting'
      >
        Setting Link
      </NavLink>
    </div>
    <div style={{ padding: '20px', margin: '10px', borderTop: '1px solid' }}>
      <Outlet />
    </div>
  </>;
}

const About = (props) => {
  return <div>
    About Compontent
  </div>;
}

const Setting = (props) => {
  return <div>
    Setting Compontent
  </div>;
}

const List = (props) => {
  return <div>
    List Compontent
  </div>;
}

const navColor = (isActive) => {
  return {color: isActive ? 'red' : ""}
}

export default App;

主要实现了给当前激活的链接设置一个式样,支持?style?和?className?这两种属性;

读取 URL 参数

// 导入 useParams 组件
import { Route, Routes, NavLink, Outlet, useParams } from 'react-router-dom';

function App() {
  return (
    <Routes>
      <Route path='/' element={<Home />} >
        <Route path='list' element={<List />} >
          <Route path=':id' element={<Item />} />
        </Route>
      </Route>
    </Routes>
  );
}

const Home = (props) => {
  return <>
    <div>
      <NavLink
        style={({ isActive }) => navColor(isActive)}
        to='/list'
      >
        List Link
      </NavLink>
    </div>
    <div style={{ padding: '20px', margin: '10px', borderTop: '1px solid' }}>
      <Outlet />
    </div>
  </>;
}

const Item = (props) => {
  // 从 URL 获取参数::id
  const params = useParams();
  return <h2>Item: {params.id}</h2>;
}

const List = (props) => {
  const list = [
    {
      name: "赵云",
      no: 100
    },
    {
      name: "马超",
      no: 101
    }
  ]
  return <div>
    {list.map((item) => {
      return (<NavLink
        style={({isActive}) => navColor(isActive)}
        to={`/list/${item.no}`}
        key={item.no}
      >
        {item.name}
      </NavLink>)
    })}
    <div className='content'>
      {/* 指定子路由 /list/? 的渲染位置 */}
      <Outlet />
    </div>
  </div>;
}

const navColor = (isActive) => {
  return {
    color: isActive ? 'red' : "",
    marginRight: '10px'
  }
}

export default App;

与 V5 的区别

  1. <Routes>?替代?<Switch>
    写法上的比较:
    // v5 写法
    // 引入 react-router
    import { Route, Switch } from 'react-router-dom';
    function App() {
      return (
    	  <Switch>
    		{/* 路由配置 */}
    	  </Switch>
      );
    }
    
    // v6 写法
    import { Route, Routes } from 'react-router-dom';
    function App() {
      return (
    	  // Routes 替换 Switch
    	<Routes> 
    	  {/* 路由配置 */}
    	</Routes>
      );
    }
    
    v6 的优点:
    v6 提供了功能更强大的?Routes?组件来代替?Switch?组件,Routes?不再按顺序匹配路径,而是采用了一种自动匹配最佳路径的方法;
  2. <Route>?不再支持子组件,改为使用?element?属性;并且不再需要?exact?属性了
    写法上的比较:
    // v5 写法
    // 引入 react-router
    import { Route, Switch } from 'react-router-dom';
    function App() {
      return (
    	  <Switch>
    		<Route exact path='/home'>
    		  <Home />
    		</Route>
    	  </Switch>
      );
    }
    
    // v6 写法
    import { Route, Routes } from 'react-router-dom';
    function App() {
      return (
    	<Routes>
    	  <Route path='/home' element={<Home /> } />
    	</Routes>
      );
    }
    
    v6 的优点:
    1. v6 提供的?element?属性, 可以使开发者更加方便的注入想要的?props;
    2. v6?中的?path?属性是相对的;
    3. 可以按照所需的任何顺序放置路由,路由器将自动检测当前URL的最佳路由;
  3. 移除了?<NavLink>?的?activeClassName?属性
    v6写法:
    import { NavLink } from 'react-router-dom';
    function App() {
      return (
    	<>
    	  {/* className 写法 */}
    	  <NavLink 
    		className={({isActive}) => {
    		  return isActive ? "highlight" : "";
    		}} 
    		to="home">Home</NavLink>
    	  {/* style 写法 */}
    	  <NavLink 
    		to="about"
    		style={({isActive}) => {
    		  return {
    			color: isActive ? "red" : ""
    		  }
    		}}
    	  >About</NavLink>
    	</>
      );
    }
    
  4. 移除?<Redirect>,改为使用?<Navigate>
    写法上的对比:
    // v6 写法
    import { Navigate, Route, Routes } from 'react-router-dom';
    function App() {
      return (
    	<Routes>
    	  <Route path='/' element={<Navigate replace to="/home" />} /> 
    	</Routes>
      );
    }
    
  5. <Link to>支持相对位置
    // 配置路由
    <Route path="app">
    	    <Route path="home">
    	        <Route path="list" />
    	    </Route>
    </Route>
    
    // 当前 URL 是 /app/home
    <Link to="list">               => <a href="/app/home/list">
    <Link to="../list">            => <a href="/app/list">
    <Link to="../../list">         => <a href="/list">
    <Link to="../../../list">      => <a href="/list">
    
  6. 新增?<Outlet>
    关于?<Outlet>,参考本文的嵌套路由节点; 此组件是一个占位符,告诉 React Router 嵌套的内容应该放到哪里; 通过?<Outlet>?可以将所有的路由(嵌套的子路由)配置合并在一起,可进行路由的统一管理,增加了代码可维护性;
  7. 使用?useNavigate?实现编程式导航,从而代替?useHistory
    // v6 写法
    import { useNavigate } from 'react-router-dom';
    function App() {
      const navigate = useNavigate();
    
      const handleClick = () => {
    	navigate('/home');  // push
    	// 重定向
    	// navigate('/home', {replace: true});
      };
    
      return (
    	<div>
    	  <button onClick={handleClick}>返回首页</button>
    	</div>
      );
    }
    
    主要写法变更:
    • history.push("/") => navigate("/")
    • history.replace("/") => navigate("/",{ replace: true })
    • history.goBack() => navigate(-1)
    • history.goForward() => navigate(1)
    • history.go(2) => navigate(2)
  8. 一系列的?Hooks
    hooks名作用说明
    useParams返回当前参数根据路径读取参数
    useNavigate返回当前路由代替原有V5中的 useHistory
    useOutlet返回根据路由生成的element
    useLocation返回当前的location 对象
    useRoutes同Routers组件一样,只不过是在js中使用
    useSearchParams用来匹配URL中?后面的搜索参数
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-25 23:09:09  更:2022-09-25 23:09:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:03:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码