最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 从Vue2.0到React17——React路由入门(二)

    正文概述 掘金(红尘炼心)   2021-08-14   530

    这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战

    前言

    React作为一个MVVM框架,路由功能是必不可少的,回顾我们在使用Vue Router的过程中,最常用的一些功能是路由页面的渲染路由页面内容的添加路由地址的配置路由跳转路由传参嵌套路由等等,本文将去React Router中寻找这些常用功能的是如何实现的,来带你入门 React Router5.0

    在上篇文章中介绍了路由页面如何渲染 、路由页面内容如何设置、如何设置路由地址,本文将继续介绍路由如何跳转、如何接收路由的传参、路由懒加载。

    一、路由如何跳转

    在Vue Router中有两种方式进行路由跳转,一种是声明式,一种是编程式。

    声明式编程式
    <router-link :to="...">router.push(...)

    那React Router中是否也有声明式和编程式的路由跳转?举一个例子来介绍,例如:实现一个点击第一个页面跳转到第二个页面,点击第二个页面跳转到第一个页面。

    1.1 声明式路由跳转

    使用 Link 组件来实现跳转,其属性to可设置要跳转的路由地址,切记 Link 组件必须在 Route 组件内使用

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { BrowserRouter, Route ,Link} from "react-router-dom";
    ReactDOM.render(
      <div>
        <BrowserRouter>
          <Route
            path="/one"
            render={() => {
              return (
                <div><Link to="/two">去第二个页面</Link></div>
              )
            }}
          >
          </Route>
          <Route
            path="/two"
            render={() => {
              return (
                <div><Link to="/one">去第一个页面</Link></div>
              )
            }}
          ></Route>
        </BrowserRouter>
      </div>,
      document.getElementById('root')
    );
    

    1.2 编程式路由跳转

    在类组件和函数组件中的用法是不同的,分别来介绍。

    1.2.1 函数组件中的编程式路由跳转

    执行useHistory() Hook 来获取history,然后调用history.push(path)进行路由跳转。

    1.2.2 类组件中的编程式路由跳转

    在类组件中通过props获取到history,然后调用history.push(path)进行路由跳转。

    具体实现看下面demo。

    import React from 'react';
    import ReactDOM from 'react-dom';
    import {
      BrowserRouter,
      Route,
      useHistory
    } from "react-router-dom";
    class OnePage extends React.Component {
      constructor(props) {
        super(props)
        const { history } = this.props;
        this.history = history;
        this.jump = this.jump.bind(this)
      }
      jump = () => {
        this.history.push('/two')
      }
      render() {
        return (
          <div>
            <div onClick={this.jump}>去第二个页面</div>
          </div>
        )
      }
    }
    const TwoPage = () => {
      const history = useHistory();
      const handleClick = () => {
        history.push("/one");
      }
      return (
        <div onClick={handleClick}>去第一个页面</div>
      )
    }
    ReactDOM.render(
      <div>
        <BrowserRouter>
          <Route
            path="/one"
            component={OnePage}
          >
          </Route>
          <Route
            path="/two"
            component={TwoPage}
          ></Route>
        </BrowserRouter>
      </div>,
      document.getElementById('root')
    );
    

    二、如何接收路由的传参

    在类组件和函数组件中的接收路由参数的做法是不同的,要分别来介绍。另外每一种接收路由的传参都对应着一种传递路由参数的方法,且在类组件和函数组件中是一致的,会穿插在每种接收路由的传参的方法中介绍。

    2.1 在函数组件中接收路由传参

    在函数组件中有三个Hook(useLocationuseParamsuseRouteMatch)可以接收路由参数,下面来详细介绍各自的使用方法。

    2.1.1 useLocation

    const location = useLocation();
    console.log(location)
    

    先在函数组件中执行useLocation,并将结果打印出来,看一下结果,如下图所示:

    从Vue2.0到React17——React路由入门(二)

    主要关注结果中的searchstate这个两个属性,这两个属性是用来接收路由的传参。

    那要怎么传参,才能用useLocation返回的对象中的searchstate接收到路由的传参。在上一小节可知路由的跳转有两种,一种是声明式,一种是编程式。

    search接收跳转地址的请求参数,如:/one?id=1时,search?id=1,可以在声明式跳转中这样传参。

    state接收history.push中的第二参数作为传参,如:history.push('/one',{name:'第一个页面'}),一般在编程式跳转中这样传参。

    import React from 'react';
    import ReactDOM from 'react-dom';
    import {
      BrowserRouter, 
      Route,
      Link,
      useLocation,
      useHistory
    } from "react-router-dom";
    const OnePage = () =>{
      const location = useLocation();
      console.log('第一个页面',location)
      return (
        <div><Link to="/two?id=2">去第二个页面</Link></div>
      )
    }
    const TwoPage= () =>{
      const location = useLocation();
      console.log('第二个页面',location)
      const history = useHistory();
      const toOnePage = () =>{
        history.push('/one',{name:'第一个页面'})
      }
      return (
        <div onClick={toOnePage}>去第一个页面</div>
      )
    }
    ReactDOM.render(
      <div>
        <BrowserRouter>
          <Route
            path="/one"
            component={OnePage}
          >
          </Route>
          <Route
            path="/two"
            component={TwoPage}
          ></Route>
        </BrowserRouter>
      </div>,
      document.getElementById('root')
    );
    

    将 OnePage 和 TwoPage 两个组件中的执行useLocation()的结果都打印出来,如下图所示:

    从Vue2.0到React17——React路由入门(二)

    当使用history.push('/one',{name:'第一个页面'})跳转到第一个页面时,useLocation()的结果中的state的值为{name: "第一个页面"}

    当使用<Link to="/two?id=2">去第二个页面</Link>跳转到第二个页面时,useLocation()的结果中的search的值为"?id=2"

    2.1.2 useParams

    useParams接收跳转地址的路径参数,如/one/1,其中1就是路径参数。

    要先用特定的写法给 Route 组件的path属性添加路径,才能用useParams接收到路径参数。

    例如path设置为/one/:id/:num,若路由跳转地址为/one/2/3/4,那么用useParams接收的值为{id:2,num:3}

    下面用一个例子具体演示一下,还是点击第一个页面跳转第二页面,点击第二个页面跳转第一页面,注意观察各自 Route 组件的path属性值、路由跳转地址和各自组件内执行useParams()的结果。

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { BrowserRouter,
      Route,
      Link,
      useHistory,
      useParams
    } from "react-router-dom";
    const OnePage = () =>{
      const params = useParams();
      console.log('第一个页面',params);
      return (
        <div><Link to="/two/2/3">去第二个页面</Link></div>
      )
    }
    const TwoPage= () =>{
      const params = useParams();
      console.log('第二个页面',params);
      const history = useHistory();
      const toOnePage = () =>{
        history.push('/one/1/3')
      }
      return (
        <div onClick={toOnePage}>去第一个页面</div>
      )
    }
    ReactDOM.render(
      <div>
        <BrowserRouter>
          <Route
            path="/one/:id/:num"
            component={OnePage}
          >
        </Route>
          <Route
            path="/two/:id"
            component={TwoPage}
          ></Route>
        </BrowserRouter>
      </div>,
      document.getElementById('root')
    );
    

    将上面demo中各自组件内执行useParams()的结果打印出来,如下图所示:

    从Vue2.0到React17——React路由入门(二)

    此外要特别注意,若给一个 Route 组件设置的path带路径参数的变量,设置几个,访问这个 Route 组件的URL也要有几个路径参数,否是访问不了。

    2.1.3 useRouteMatch

    执行useRouteMatch()可得到当前路由页面的路由数据。数据中有个params的字段,其值和执行useParams()得到数据一样。

    所以使用useRouteMatch获取路由参数,也要先用特定的写法给 Route 组件的path属性添加路径,才能用useRouteMatch接收到路径参数。

    例如将渲染“第一页面”的 Route 组件的path设置为/one/:id/:num,若路由跳转地址为/one/2/3/4,那么在“第一页面”路由页面组件中执行useRouteMatch()

    import {
      useRouteMatch
    } from "react-router-dom";
    const OnePage = () =>{
      const match = useRouteMatch();
      console.log(match);
      return (
        <div>第一个页面</div>
      )
    }
    

    可得到当前路由页面的路由数据match如下所示:

    从Vue2.0到React17——React路由入门(二)

    其中红框部分就是路由参数,是不是和执行useParams()得到数据一样?

    2.2 在类组件中接收路由传参

    在类组件中通过props获取到locationmatch,然后在其中获取到路由参数search(请求参数)、params(路径参数)和state

    在“第一页面”这个路由页面组件中把props打印出来。

    class OnePage extends React.Component {
      constructor(props) {
        super(props)
        console.log(this.props)
      }
      render() {
        return (
          <div>
            <div>第一个页面</div>
          </div>
        )
      }
    }
    

    打印结果如下图所示:

    从Vue2.0到React17——React路由入门(二)

    至于路由参数search(请求参数)、params(路径参数)和state如何传递已经在上小节【在函数组件中接收路由传参】中介绍过了。

    三、路由懒加载

    使用React.lazy定义一个动态加载的组件,来实现路由懒加载。

    例如把OnePage这个路由页面组件进行懒加载,实现代码如下所示:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import {
      BrowserRouter,
      Route,
    } from "react-router-dom";
    const OnePage = React.lazy(() => import('./OnePage'));
    const Spinner = () => {
      return (
        <div>加载中……</div>
      )
    }
    ReactDOM.render(
      <div>
        <React.Suspense fallback={<Spinner/>}>
          <BrowserRouter>
            <Route
              path="/"
              component={OnePage}
            >
            </Route>
          </BrowserRouter>
        </React.Suspense>
      </div>,
      document.getElementById('root')
    );
    

    起源地下载网 » 从Vue2.0到React17——React路由入门(二)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元