• reactrouterdom 在hook中的使用 v6 和 v5的对比


    前言

    react-router-dom 是react中通用的路由组件,随着新版本的更新,尤其是为了配合 react hook 的 v6版本,已经在使用上有了较大的变化,本文旨在对比旧版本(v5),以及介绍新版本的使用



    react-router-dom 的版本介绍

    v5文档: https://v5.reactrouter.com/web/guides/quick-start

    本文使用的两个版本: v5(5.3.0) 和 v6(6.1.1)
    其中:
    v5版本既兼容了 class component(react v16.8前),又兼容了function component(v16.8及以后,即hook)
    v6版本,若仍然使用this.props.history.push(),此时props会提示是空值,v6文档里把路由组件默认接受的三个属性给移除了,官网文档里给出的解决方案是使用useNavigate()这个hook,但是hook只能存在于无状态组件(function component),无法用在类组件中(class component)

    所以,仍然使用class commponent(类组件)进行项目开发的,建议react-router-dom 使用v5及以前的版本(最新的v5版本是 v5.3.0)
    如果使用 function component(函数组件)进行项目开发的,建议使用最新的v6版本(v5版本虽然兼容了hook用法,但是相比v6还是有点区别)



    react-router-dom 在 class component 类组件中的用法(v5.3.0)

    import React from "react";
    import { Router, Route, Switch, Redirect, HashRouter } from "react-router-dom";
    import { createHashHistory } from "history";
    ...
    
    const route = () => (
      <HashRouter>
        <Switch>
          {/* 不可放在首行 */}
          {/* <Redirect path="*" to="/" /> */}
          <Route exact path="/" component={Home} />
          <Route exact path="/listPage" component={ListPage} />
          <Route exact path="/detailPage/:id" component={DetailPage} />
          {/* 其他匹配重定向 */}
          <Redirect path="*" to="/" />
        </Switch>
      </HashRouter>
    );
    
    export default route;
    

    注意:<Router history={createHashHistory()}><HashRouter> 的区别 ==> 似乎没有区别

    路由跳转:
    this.props.history.push('/listPage'): 路由入栈
    this.props.history.replace('/listPage'):路由替换

    路由返回:
    this.props.history.goBack();: 返回上一级路由

    携带参数:
    state属性携带参数: (隐式传参)

    this.props.history.push({
      pathname: '/listPage',
      state: {
        aaa: 123
      },
    });
    // 跳转后新页面 通过 this.props.history.location.state 获取
    // http://localhost:3000/#/listPage
    

    search属性携带参数:(显式传参)

    this.props.history.push({
      pathname: '/listPage',
      search: '?bbb=456',
    });
    // 跳转后新页面 通过 this.props.history.location.search 获取
    // url: http://localhost:3000/#/listPage?bbb=456
    

    路由传参携带参数: (显式传参,需要router.js 中配合)

    this.props.history.push({
      pathname: '/detailPage' + '/' + id,
    });
    // 需要router.js 中路由配合: <Route exact path="/detailPage/:id" component={DetailPage} />
    // 跳转后新页面 通过this.props.match.params.id 获取
    // url: http://localhost:3000/#/detailPage/789
    


    react-router-dom 在 function component 函数组件中的用法(v6.1.1),即hook

    import React from "react";
    import { HashRouter, Route, Routes, Navigate } from "react-router-dom";
    ...
    
    const route = () => (
      <HashRouter>
        <Routes>
          <Route exact path="/" element={<Home />} />
          <Route exact path="/listPage" element={<ListPage />} />
          <Route exact path="/detailPage/:id" element={<DetailPage />} />
          <Route exact path="*" element={<Navigate to="/" />} />
          {/* <Route exact path="*" element={<NotFound />} /> */}
        </Routes>
      </HashRouter>
    );
    
    export default route;
    

    注意点:

    1. Routes 替换了 Switch
    2. Route中 element 替换了 component/render 属性,且值是组件,而非组件名
    3. Navigate 组件替换了 Redirect

    路由跳转

     import { useNavigate } from 'react-router-dom';
     const navigate = useNavigate();
     // push
     navigate(path);
     // replace
     navigate(path, {replace: true});
    

    路由返回

     const navigate = useNavigate();
     // go back
     navigate(-1);
    

    携带参数:
    state属性携带参数: (隐式传参)

     const navigate = useNavigate();
     navigate('/listPage', {
       state: {
         aaa: '123',
       }
     })
     // url: http://localhost:3000/#/listPage
    

    search属性携带参数:(显式传参)

     const navigate = useNavigate();
     navigate('/listPage' + '?bbb=456')
     // url: http://localhost:3000/#/listPage?bbb=456
    

    路由传参携带参数: (显式传参,需要router.js 中配合)

     const navigate = useNavigate();
     navigate('/detailPage' + '/' + id)
    // 需要router.js 中路由配合: <Route exact path="/detailPage/:id" element={<DetailPage />} />
    // 跳转后新页面 通过 const { id } = useParams(); 获取,其中useParams 为 react-router-dom 内方法
    // url: http://localhost:3000/#/detailPage/789
    


    总结

    v5 和 v6 的比较:
    router.js 路由文件中:

    1. Switch 改用 Routes
    2. component/render 属性 改为 element
      <Route exact path="/listPage" element={<ListPage />} />
    3. Redirect 改用 Navigate
      <Route exact path="*" element={<Navigate to="/" />} />

    路由跳转、传参:

    1. history.push(path) 改为 navigate(path)
    2. history.replace(path) 改为 navigate(path, {replace: true})
    3. history.goBack() 改为 navigate(-1)
    4. v5 中的 hook 使用比较:
      -v5: 使用 useHistory 的 history.push()
      -v6: 使用 useNavigate 的 navigate()


    参考

    https://juejin.cn/post/7042849947451916296
    https://juejin.cn/post/7040289734836355085
    https://juejin.cn/post/6862305213148381198

  • 相关阅读:
    代码审核工具是gerrit
    Redis分布式缓存承载于 “Microsoft.Extensions.Caching.Redis”这个NuGet包
    .Net Core之JWT授权
    什么是前端路由
    为什么需要线程池?什么是池化技术?
    架构模式
    UI 多线程处理 WPF
    项目管理艺术
    项目与项目管理
    使用 MicroK8s 和 OpenEBS 扩展 Kubernetes 存储
  • 原文地址:https://www.cnblogs.com/nangezi/p/15733562.html
Copyright © 2020-2023  润新知