React Route5 路由

这篇具有很好参考价值的文章主要介绍了React Route5 路由。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

💻 React Route5 路由🏠专栏:React
👀个人主页:繁星学编程🍁
🧑个人简介:一个不断提高自我的平凡人🚀
🔊分享方向:目前主攻前端,其他知识也会阶段性分享🍀
👊格言:☀️没有走不通的路,只有不敢走的人!☀️
👉让我们一起进步,一起成为更好的自己!!!🎁

React Route5 路由

一切皆组件,默认是history模式

安装

yarn add react-router-dom@5

起步

(1) 从react-router-dom中引入BrowserRouter

import { BrowserRouter } from 'react-router-dom'

如果想要使用路由,那么所有和路由相关的内容都要放在BrowserRouter的里面

<BrowserRouter>
    <h2>Hello Router</h2>  
</BrowserRouter>

注:如果整个项目都要使用路由,可以将BrowserRouter组件写到index.js项目入口文件中,并包裹组件。

(2) 从react-router-dom中引入Link

import { Link } from 'react-router-dom'
<BrowserRouter>
  <ul>
    <li>
      <Link to="home">首页</Link>
    </li>
    <li>
      <Link to="about">关于页</Link>
    </li>
  </ul>
</BrowserRouter>

Link组件相当于Vue中的router-link
Link的to属性用于改变url

(3) 从react-router-dom中引入Route

import { Route } from 'react-router-dom'

Route组件是用来切换内容,相当于Vue中的router-view

<Route path="/home" component={Home}></Route>
<Route path="/about" component={About}></Route>

Route组件中的所有属性:

  • path:指定 URL 路径匹配规则的字符串,可包含变量和正则表达式。
  • exact:当为 true 时,只有 URL 路径与 path 属性完全匹配时才渲染当前组件。
  • strict:当为 true 时,要求 URL 路径结尾必须为斜线 /
  • sensitive:当为 true 时,表示 URL 匹配时,将大小写视为敏感。
  • component:指定路由匹配成功后要渲染的 React 组件。
  • render:一个返回 React 组件的函数,可以根据需要动态渲染组件。
  • children:一个返回 React 元素的函数,无论 URL 是否匹配,都将被调用并渲染为子元素。


react的路由是:包容性路由(无论匹没匹配到想要的路由,都会匹配一遍所有的路由)
vue的路由是:排他性路由(从路由表上向下进行匹配,找到就不会向下匹配)

react的路由想要成为排他性路由方式

// 1. 从react-router-dom中引入Switch
import { Switch } from 'react-router-dom'
// 2. 将Switch组件包裹在Route组件外层
<Switch>
  <Route path="/home" component={Home}></Route>
  <Route path="/about" component={About}></Route>  
</Switch>

Switch组件是用来包裹Route组件的,用于路由匹配的时候,只匹配一个,也就是将包容性路由转换成排他性路由

存在的问题:当首页的路由是的url路径是:/ 时,会出现无论你点击切换到哪个组件时,Home组件的内容都会显示。

解决方式

  1. 将url为 / 的Route放到最下面
  2. 在Route中添加 exact 属性,进行精准匹配

路由嵌套

路由嵌套就是在其中的一个子路由里面继续使用Link和Route组件

import React from 'react'
import { Link, Route } from 'react-router-dom';
import Detail from './Detail'
const Home = () => {
    return (
        <>
            <p>欢迎进入首页</p>
            <ul>
                <li>
                    <Link to='/home/detail'>详情页</Link>
                </li>
            </ul>
            <hr />
            <Route path='/home/detail' component={Detail}></Route>
        </>
    );
}

export default Home;

注意:如果一个路由有下一级的路由,那么这个路由就不要加exact属性,会使得当前路由及其子路由都显示不出来。

当一个组件变成路由组件后,那么props里面会自动有路由信息。
此时可以通过:

// 类组件
const {
    match: { path },
} = this.props
// 函数组件
const { match: { path } } = props

拿到一级路由的url,就可以在编写二级路由的url的时候,使用变量代替一级路由的url。

这样写的好处:只要直接修改一级路由的url所有的二级路由中的url就可以不需要修改,直接使用。

const {
    match: { path },
} = this.props
// 原来写法:
<Route path="/home/sale" component={Sale}></Route>
<Route path="/home/about" component={About}></Route>
// 使用变量:
<Route path={`${path}/sale`} component={Sale}></Route>
<Route path={`${path}/about`} component={About}></Route>

动态路由

params传参(/detail/:id)

react中动态路由的写法和vue是完全一样的,也是例:/detail/:id

<ul>
  <li>
    <Link to="/home/detail/234">详情页</Link>
  </li>
  <li>
    <Link to="/home/detail/567">详情页</Link>
  </li>
</ul>
<Route path="detail/:id" component={Detail}></Route>
const Detail = (props) => {
    // ? 可选链操作符,表示可有可无
    const id = props.match?.params?.id;
}

query传参(/detail?id=123&name=‘zs’)

传递/detail?id=123&name=‘zs’

  • 方式一:字符串格式
// 方式一:
<Link to="/detail?id=123&name=zs">详情页</Link>
<Route path="detail" component={Detail}></Route>
  • 方式二:对象格式
// 方式二:
<Link to={{
          pathname: '/detail',
          search: '?id=123&name=zs',
          hash: '#abz',
          // 在url上面不可见的传参方式
          state:{
            x: 10,
            y: 20
            }
         }}></Link>
<Route path="detail" component={Detail}></Route>

获取/detail?id=123&name='zs’中的id

  • 方式一:查询字符串转对象
// 要转换的查询字符串
var str = "name=zs&age=18";
// 封装一个函数
function parseQueryString(str) {
    // 准备一个接收的空对象
    var obj = {};
    // 将每一个数值分隔开
    var s1 = str.split('&');
    // console.log(s1); // ['name=zs', 'age=18']
    // 将数组中的值依次放入对象中
    s1.forEach(function(item) {
        // 将每个数组里面的字符串按照等号分割开,得到若干个数组
        var t = item.split('=');
        var key = t[0];
        var value = t[1];
        obj[key] = value;
    });
    return obj;
}
// 调用函数
var result = parseQueryString(str);
console.log(result); // {name: 'zs', age: '18'}
  • 方式二:通过 new URL()
const Detail = (props) => {
  // 2.通过 new URL():必须有一个基准地址才能解析
  const urlObj = new URL('http://www.a.com' + props.location.search)
  const id = obj.searchParams.get("id")
}
  • 方式三:通过new URLSearchParams()
  // 3.通过new URLSearchParams()
  const urlObj = new URLSearchParams(props.location.search);
  const id = urlObj.get("id")

路由组件渲染方式

使用component属性来渲染路由组件(很多情况下使用)

<Route path="/home" component={Home}></Route>

使用render属性来渲染路由组件

<Route path="/about" render={About}></Route>
  • 与component属性方式的区别:render属性不能渲染类组件

    如果想要渲染类组件可以通过:在类组件的外面套一层函数(() => )
    因此,通过render属性里面的函数形式,就可以进行条件判断,进行路由鉴权操作

<Route path="/about" render={
 (props) => {
   // 做路由鉴权
   if(token){
       <Cart/>
   }else{
       <Login/>
   }
}>
</Route>

使用children属性来渲染路由组件

<Route path="/mine" children={Mine}></Route>

特点

  • 当没有Switch组件的时候,children的效果是不管是否匹配都会直接渲染
  • 当有Switch组件的时候,children属性效果和render属性完全一样

使用Route插槽来渲染路由组件

<Route path="/cart">
<Cart />
</Route>

特点:

  • 既可以渲染类组件,也可以渲染函数组件
  • 缺点:但是渲染的组件默认是没有路由信息的

解决没有路由信息方式:

可以通过withRouter
withRouter是一个高阶组件,作用是让那些没有路由信息的组件直接拥有路由信息

// 1. 从react-router-dom解构withRouter高阶组件
import {withRouter} from "react-router-dom";

// 2. 使用withRouter
class Cart extends React.Component {
  render() {
    console.log(this.props);
    return <div>购物车页面</div>;
  }
}
const Cart2 = withRouter(Cart);

4个hooks来帮助获取
分别是:useHistory、useLocation、useParams、useRouteMatch
相比withRouter,使用hooks方式的好处:hooks不会使组件层级变深

// 1. 从react-router-dom解构hooks
import {
  useHistory,
  useLocation,
  useParams,
  useRouteMatch,
} from "react-router-dom";
// 2. 函数组件使用
const Cart = () => {
  const location = useLocation();
  console.log(location);
  const histroy = useHistory();
  console.log(histroy);
  const match = useRouteMatch();
  console.log(match);
  const params = useParams();
  console.log(params);
  return <div>购物车页面</div>;
};

路由重定向

解构Redirect组件

// 从react-router-dom中解构Redirect组件
import { Redirect } from 'react-router-dom';

使用Redirect组件

<Redirect from="/" to="/home"></Redirect>  
  • from属性:指定源路径
  • to属性:指定目标路径
// 解构Route和Switch组件
import { Switch, Route } from 'react-router-dom';
<Switch>
  <Redirect from="/" to="/home" exact></Redirect>
  <Route></Route>
</Switch>  

需要注意的点
在使用重定向时,为了防止重定向匹配到与路径相似的所有路径。可以采取以下两种方式:

  • 可以添加exact属性
  • 可以将Redirect组件放所有Route组件的最下面

路由鉴权

封装的路由鉴权的组件

const Auth = (props) => {
  return (
    <Route
      path={props.path}
      render={() => {
        if (localStorage.getItem("token")) {
          return props.children;
        } else {
          return (
            <Redirect
              from={props.path}
              to={{
                pathname: "/login",
                state: {
                  from: props.path,
                },
              }}
            ></Redirect>
          );
        }
      }}
    ></Route>
  );
};

使用路由

<Switch>
  <Redirect from="/" to="/home" exact></Redirect>
  <Route path="/home" component={Home}></Route>

  <Auth path="/about">
    <About />
  </Auth>
  <Auth path="/mine">
    <Mine />
  </Auth>
  <Route path="/login">
    <Login />
  </Route>
</Switch>

编程式导航

编程式导航:通过使用histroy对象下面的push/replace/go/goBack/goForward

// 1. 从react-router-dom中解构useHistory 
import {useHistory} from "react-router-dom";
// 2. 使用编程式导航
const login = () => {
  localStorage.setItem("token", "12345");
  histroy.push(location.state.from);
};

react-router-dom的history对象中常见的方法有以下几种,它们分别是:

  • push(path, [state]): 将新的URL添加到历史记录中,从而进行页面导航。path为要跳转的页面路径,state为要传递给该页面的状态对象。
  • replace(path, [state]): 替换当前历史记录中的URL,并使用新的URL进行导航。path为要跳转的页面路径,state为要传递给该页面的状态对象。
  • go(n): 在浏览器历史记录中前进或后退指定的步数,例如go(1)代表前进一步,go(-1)代表后退一步。
  • goBack(): 后退一步。
  • goForward(): 前进一步。
  • listen(listener): 添加一个持续监听历史记录变化的回调函数,该函数会在历史记录发生变化时被调用,并返回一个用于卸载该回调函数的函数。

NavLink

NavLink和Link一样,是用来做路由跳转的
Link的功能NavLink都有,并且多了一个高亮的效果

// 1. 从react-router-dom中解构NavLink
import { Route, NavLink } from "react-router-dom";

<ul>
  <li>
    <NavLink to="/home" activeClassName="select">
      首页
    </NavLink>
  </li>
  <li>
    <NavLink to="/about" activeClassName="select">
      关于页
    </NavLink>
  </li>
</ul>

使用NavLink组件会在组件上自动添加名为active的类名,用于写高亮的样式
如果要修改active的类名,可以直接使用activeClassName类名
NavLink组件也可以添加exact进行高亮的精准匹配

Prompt

Prompt是React Router中的一种路由组件,它用于在用户离开当前页面之前显示一个确认对话框。

作用:可以防止用户意外地离开当前页面,提示用户保存未提交的信息或确认他们要离开当前页面。
Prompt相当于Vue路由导航守卫中的beforeRouteLeave

Prompt 组件的两个属性

  • when 属性设置为 isDirty,这意味着只有当 isDirtytrue 时,确认对话框才会显示。
  • message 属性用来指定确认对话框上显示的消息。
import { Prompt } from 'react-router-dom';

function MyForm() {
  const [isDirty, setIsDirty] = useState(false);

  const handleFormChange = () => {
    setIsDirty(true);
  };

  return (
    <form onChange={handleFormChange}>
      <label htmlFor="name">Name:</label>
      <input type="text" id="name" />

      <Prompt
        when={isDirty}
        message="Are you sure you want to leave without saving?"
      />
    </form>
  );
}

404页面

path=“*”

<Switch>
  <Redirect from="/" to="/home" exact></Redirect>
  <Route path="/home" component={Home}></Route>
  <Route path="/about" component={About}></Route>
  {/* 404路由 */}
  <Route path="*" component={NotFound}></Route>
</Switch>

注意点:

  • 要写在所有Route的最下面

    不放在最下面,会跳转导致404 Route以下的Route时都跳转404

  • 必须要和Switch组件一起使用

    不使用Switch组件时,无论要跳转到哪个页面404页面都会一起存在

路由表

在App.jsx同级目录下新建router文件夹并在其文件夹中新建Index.jsx文
引入根组件及其各级路由

import React from 'react'
import { Route, Redirect } from 'react-router-dom'
// 引入根组件
import App from '../App';
// 引入一级路由
import Home from '../pages/home/Index'
import Detail from '../pages/detail/Index'
import Login from '../pages/login/Index'
import City from '../pages/city/Index'
import NotFound from '../pages/notfound/Index'
// 引入二级路由
import Movies from '../pages/home/movies/Index'
import Videos from '../pages/home/videos/Index'
import Mini from '../pages/home/mini/Index'
import Show from '../pages/home/show/Index'
import Mine from '../pages/home/mine/Index'
// 引入三级路由
import Hot from '../pages/home/movies/hot/Index'
import Wait from '../pages/home/movies/wait/Index'
import Cinema from '../pages/home/movies/cinema/Index'
import Classic from '../pages/home/movies/classic/Index'

将组件嵌套渲染

const Index = () => {
  return (
      <App>
          <Redirect from="/" to='/home' exact></Redirect>
          <Route path='/home'>
              <Home>
                  <Redirect from='/home' to='/home/movies' exact></Redirect>
                  <Route path='/home/movies'>
                      <Movies>
                          <Redirect from='/home/movies' to='/home/movies/hot' exact></Redirect>
                          <Route path='/home/movies/hot'><Hot /></Route>
                          <Route path='/home/movies/wait'><Wait /></Route>
                          <Route path='/home/movies/cinema'><Cinema /></Route>
                          <Route path='/home/movies/classic'><Classic /></Route>
                      </Movies>
                  </Route>
                  <Route path='/home/videos'><Videos /></Route>
                  <Route path='/home/mini'><Mini /></Route>
                  <Route path='/home/show'><Show /></Route>
                  <Route path='/home/mine'><Mine /></Route>
              </Home>
          </Route>
          <Route path='/detail/:id'><Detail /></Route>
          <Route path='/login'><Login /></Route>
          <Route path='/city'><City /></Route>
          <Route path='*'><NotFound /></Route>
      </App>
  );
}

导出Index组件

export default Index;

在入口文件index.js中,将原本引入App组件改为引入路由组件Index
在原先放置各级路由的组件中使用props.children接收路由表中的路由

// eg:
const App = (props) => {
  return (
      <>
          <Switch>
              {props.children}
          </Switch>
      </>
  );
}

路由懒加载

从react中解构lazy方法,然后进行按需引入

// 1.从react中解构lazy方法
import { lazy } from 'react'

原来写法

import Home from '../pages/home/Index'

改为按需引入

const Home = lazy(() => import('../pages/home/Index'))

封装懒加载组件
fallback={}中可以是标签或组件<Child/>

import React, { Suspense } from 'react'

const Lazys = (props) => {
  return (
      <Suspense fallback={<div>loading...</div>}>{props.component}</Suspense>
  );
}

export default Lazys;

进行路由懒加载

// 引入封装的组件
import Lazys from './Lazys';
// 懒加载处理后的路由表
const Index = () => {
  return (
      <App>
          <Redirect from="/" to='/home' exact></Redirect>
          <Route path='/home'>
              <Lazys component={
                  <Home>
                      <Redirect from='/home' to='/home/movies' exact></Redirect>
                      <Route path='/home/movies'>
                          <Lazys component={
                              <Movies>
                                  <Redirect from='/home/movies' to='/home/movies/hot' exact></Redirect>
                                  <Route path='/home/movies/hot'>
                                      <Lazys component={<Hot />} />
                                  </Route>
                                  <Route path='/home/movies/wait'>
                                      <Lazys component={<Wait />} />
                                  </Route>
                                  <Route path='/home/movies/cinema'>
                                      <Lazys component={<Cinema />} />
                                  </Route>
                                  <Route path='/home/movies/classic'>
                                      <Lazys component={<Classic />} />
                                  </Route>
                              </Movies>
                          } />
                      </Route>
                      <Route path='/home/videos'>
                          <Lazys component={<Videos />} />
                      </Route>
                      <Route path='/home/mini'>
                          <Lazys component={<Mini />} />
                      </Route>
                      <Route path='/home/show'>
                          <Lazys component={<Show />} />
                      </Route>
                      <Route path='/home/mine'>
                          <Lazys component={<Mine />} />
                      </Route>
                  </Home>
              } />
          </Route>
          <Route path='/detail/:id'>
              <Lazys component={<Detail />} />
          </Route>
          <Route path='/login'>
              <Lazys component={<Login />} />
          </Route>
          <Route path='/city'>
              <Lazys component={<City />} />
          </Route>
          <Route path='*'>
              <Lazys component={<NotFound />} />
          </Route>
      </App >
  );
}

结束语

希望对您有一点点帮助,如有错误欢迎小伙伴指正。
👍点赞:您的赞赏是我前进的动力!
⭐收藏:您的支持我是创作的源泉!
✍评论:您的建议是我改进的良药!
一起加油!!!💪💪💪文章来源地址https://www.toymoban.com/news/detail-609421.html

到了这里,关于React Route5 路由的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端框架之争:Vue.js vs. React.js vs. Angular

    🎉欢迎来到Web前端专栏~前端框架之争:Vue.js vs. React.js vs. Angular ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:架构设计 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和水平有限,如果

    2024年02月07日
    浏览(93)
  • 如何使用前端框架(React、Angular、Vue.js等)?该如何选择?

    聚沙成塔·每天进步一点点 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发者,这里都将为你提供一个系统而

    2024年02月07日
    浏览(60)
  • 前端刷新页面的五种方法(含原生js、vue和react)

    1、window.history.go(0)方法 2、location.reload()方法 3、location.href=location.href方法 4、vue-router方法 5、react-router方法

    2024年02月16日
    浏览(51)
  • 【前端】html2canvas生成图片空白排查data:;(js vue react uniapp)

    因为要做一个分享图,就用到了html2canvas,一开始是好好的,今天随便测了下,发现图片显示不出来了。打印了下,生成的图片链接变成了 data:; 。后面一步一步地排查,发现是页面内容太多了,删减一点内容就能显示出来。然后我又去认真看了下html2canvas的各个参数,发现可

    2024年02月03日
    浏览(59)
  • react+vue 前端国密算法sm2、sm3 、sm4的js ts实现

    1. 简单介绍下SM2 和 SM3 SM2 算法:是一种公钥加密算法,它的密钥长度为 256 位,安全性较高。可用于数字签名、密钥协商等场景。 SM3 算法:是一种对称加密算法,用于消息摘要和数字签名等场景。它的密钥长度为 256 位,安全性较高。SM3 算法与 SM2 算法相互配合,提高了整体

    2024年01月19日
    浏览(41)
  • 简介:在这篇教程中,我们将使用React.js框架创建一个简单的聊天机器人的前端界面,并利用Dialogflo

    作者:禅与计算机程序设计艺术 介绍及动机 聊天机器人(Chatbot)一直是互联网领域中的热门话题。而很多聊天机器人的功能都依赖于人工智能(AI)技术。越来越多的企业希望拥有自己的聊天机器人系统,从而提升自己的竞争力。为此,业界也出现了很多基于开源技术或云

    2024年02月06日
    浏览(59)
  • 0604嵌套路由与路由传参-react路由-react

    1.1 使用 示例效果如下图1.1-1所示: 该示例代码其他部分和上一篇相同,这里主要讲解下嵌套路由的使用。 分析:home组件中嵌套了News和Message两个路由组件。 创建News组件 在原项目结构Home文件夹下创建News/index.jsx 源代码1.1-1如下所示 创建Message组件 Home文件夹下创建Message/ind

    2024年02月06日
    浏览(86)
  • react基础-React原理揭秘&React路由基础

    能够说出React组件的更新机制 能够对组件进行性能优化 能够说出虚拟DOM和DIff算法 setState() 的两个作用 修改state 更新组件 过程:父组件重新渲染时,也会重新渲染子组件,但只会渲染当前组件子树(当前组件以其所有子组件) 减轻state 减轻state:只存储跟组件渲染相关的数据

    2024年02月12日
    浏览(46)
  • 0601概述-react路由-react

    1.1 简述 单页面应用和多页面应用是两种不同的 Web 应用程序架构。 单页面应用(SPA)是指在一个 HTML 页面中动态加载和渲染所有的应用程序内容,通过前端 JavaScript 操作来实现页面的变化和交互。SPA 不需要每次请求新的 HTML 页面,因此可以提供更快的响应速度和更好的用户

    2023年04月23日
    浏览(44)
  • React笔记(六)React路由

    一、React路由简介 React 官方并没有提供对应的路由插件,因此,我们需要下载第三方的路由插件 —— React Router DOM。 React Router 在 2021 年 11 月份的时候更新 v6 的版本。本次课就主要讲解V6版本 二、路由配置 1、下载路由 在项目根目录中,通过以下命令 2、路由配置 1)首先在

    2024年02月10日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包