zoukankan      html  css  js  c++  java
  • reactrouterdom 【V6新变化】

    react-router-dom

    react-router-dom v6整体体验相对于v5,体验要好很多,最大的一个改变,就是曾经的Route不可嵌套,整个路由配置必须拆分成若干小块,除非通过react-router-config这种插件,才可以实现对整个路由的管理,然而现在,不需要任何插件就可以实现对路由配置的管理。

    安装

     npm install --save react-router-dom history
    

    react,react-router-dom以及相关插件版本

    "dependencies": {
      "history": "^5.1.0",
      "react": "^17.0.2",
      "react-dom": "^17.0.2",
      "react-router-dom": "^6.0.2"
    }
    

    如果是自己通过webpack配置的项目,一定要在devServe中配置historyApiFallback,以及output.publicPath解决history模式页面刷新后出现404情况。

    devServer: {
      port,
      host,
      hot: true,
      open: true,
      historyApiFallback:{
        disableDotRule: true
      }
    },
    
    // 以及 `output` 中的 publicPath
    output: {
      path: path.resolve(__dirname, "../dist"),
      filename: "[name].[chunkhash].js",
      publicPath: '/'
    },
    

    使用
    在文件中直接渲染Router.tsx

    // idex.tsx
    import React from "react";
    import ReactDOM from "react-dom";
    import Router from "./router/Router";
    import "./index";
    
    ReactDOM.render(<Router />, document.getElementById("root"));
    

    【1】Routes组件替换V5的Switch组件

    • Route组件必须使用Routes嵌套
    //Router.tsx
    import React from 'react';
    import {BrowserRouter,Route,Routes} from 'react-router-dom';
    import Home from '../home/Home';
    import Goods from '../goods/Goods';
    import Customer from '../customer/Customer';
    
    export defealt function Router(){
    //所有的路由配置均在BrowserRouter内部
    	return(
    	<BrowserRouter>
    	  {/* 使用 Routes 替换曾经的 Switch */}
          <Routes>
            <Route path='/' element={<Home />} />
            <Route path='goods' element={<Goods />} />
            <Route path='customer' element={<Customer />} />
          </Routes>
    	<BrowserRouter/>
    	)
    }
    

    【2】跳转

    • 通过Link组件跳转
    //Customer.tsx
    import React from 'react';
    import {Link} from "react-router-dom";
    export default function Customer(){
    return(
    	<div>
    	<h2>Customer Page</h2>
    	<Link to="/goods">to Goods</Link>
    	</div>
    )
    }
    
    • 通过useNavigate方法跳转
    //Goods.tsx
    import React from 'react';
    import {useNavigate} from 'react-router-dom';
    
    export default function Goods(){
     const navigate = useNavigate();
     const handleClickToHome = ()=>{
     	navigate("/");
    	//history的replace模式
    	//navigate('/',{replace:true})
     };
     return (
     	<div>
    	<h2>Goods Page</h2>
    	<button onClick={handleClickToHome}>to Home</button>
    	</div>
     )
    }
    

    【3.匹配未定义的路由】

    • v6移除了Redirect组件,改用Navigate组件。
    // Router.tsx
    import React from "react";
    import { BrowserRouter, Route, Routes, Navigate } from "react-router-dom";
    import Home from "../home/Home";
    import Goods from "../goods/Goods";
    import Customer from "../customer/Customer";
    import NotFound from "../not-found/NotFound";
    
    export default function Router() {
      {/* 所有的路由配置均在 BrowserRouter 内部 */ }
      return (
        <BrowserRouter>
    
          {/* 使用 Routes 替换曾经的 Switch */}
          <Routes>
            <Route path='/' element={<Home />} />
            <Route path='goods' element={<Goods />} />
            <Route path='customer' element={<Customer />} />
    
            {/* 重定向到首页 */}
            <Route path="*" element={<Navigate to="/"/>} />
    
            {/* 或者跳转到 NotFound */}
            {/* <Route path="*" element={<NotFound />} /> */}
          </Routes>
        </BrowserRouter>
      );
    }
    

    【4】嵌套路由与动态路由

    • 嵌套路由的path可以不用写父级,会直接拼写;
    • 动态路由通过:style的形式实现;
    • 由于/goods/list的匹配度大于/goods/*,所以输入精确地址会精确匹配,而不是匹配到动态路由;
    • 嵌套路由必须在父级追加 Outlet 组件,作为子级组件的占位符,类似于vue-router中的router-view。
    // Router.tsx
    import React from "react";
    import { BrowserRouter, Route, Routes } from "react-router-dom";
    import Home from "../home/Home";
    import Goods from "../goods/Goods";
    import Customer from "../customer/Customer";
    import NotFound from "../not-found/NotFound";
    import GoodsDetail from "../goods/goods-detail/GoodsDetail";
    import GoodsList from "../goods/goods-list/GoodsList";
    
    export default function Router() {
      return (
        <BrowserRouter>
          <Routes>
            <Route path='/' element={<Home />}>
              <Route path='goods' element={<Goods />} >
                {/* 动态路由 */}
                <Route path=":id" element={<GoodsDetail />}/>
                <Route path="list" element={<GoodsList />}/>
              </Route>
    
              <Route path='customer' element={<Customer />} ></Route>
            </Route>
    
            <Route path="*" element={<NotFound />} /> 
          </Routes>
        </BrowserRouter>
      );
    }
    // Home.tsx
    import React from "react";
    import { Outlet, Link } from "react-router-dom";
    
    
    export default function Home() {
    
      return (
        <div>
          <h1>Home</h1>
          <p>
            <Link to='/goods'>to goods</Link>
          </p>
    
          <p>
            <Link to='/customer'>to customer</Link>
          </p>
    
          <Outlet />
        </div>
      );
    }
    
    // Goods.tsx
    import React from "react";
    import { useNavigate, Outlet } from "react-router-dom";
    
    
    export default function Goods() {
      const navigate = useNavigate();
    
      const handleClickToHome = () => {
        navigate("/");
    
        // history 的 replace 模式
        // navigate("/", { replace: true });
      };
      
      return (
        <div>
          <h2>Goods Page</h2>
    
          <button onClick={handleClickToHome}>to Home</button>
    
          {/* 子路由的占位组件 */}
          <Outlet />
        </div>
      );
    }
    

    【5】获取路由的参数

    • useParams获取动态路由的值;
    • useSearchParams获取查询字符串的值。
    // GoodsDetail.tsx
    import React,{ useEffect } from "react";
    import { useParams, useSearchParams  } from "react-router-dom";
    
    export default function GoodsDetail() {
      // 获取动态路由的值
      const params = useParams();
    
      // 获取查询字符串的值
      const [searchParams, setSearchParams] = useSearchParams();
      
    
      useEffect(() => {
        // 一个对象,key 为动态字符串的 key
        console.log(params); // {id: '123'}
    
        // 一个对象,但是不可直接点出属性
        console.log(typeof searchParams); // object
    
        // 输入 http://localhost:3304/goods/123?name=nihao
        console.log(searchParams.get("name")); // nihao
      }, []);
    
      const handleAddParams = () => {
        // 修改 查询字符串 的数据
        setSearchParams({
          name:"xxx"
        });
      };
      
      return (
        <div>
          <h2 onClick={handleAddParams}>GoodsDetail Page</h2>
        </div>
      );
    }
    

    【6】默认路由

    • 当页面又多个子路由,比如在/goods时,页面展示商品列表;/goods/:id时,展示某个商品的详情。

    • Route的Index属性就是用来展示默认子路由的。

    import React from "react";
    import { BrowserRouter, Route, Routes } from "react-router-dom";
    import Home from "../home/Home";
    import Goods from "../goods/Goods";
    import Customer from "../customer/Customer";
    import NotFound from "../not-found/NotFound";
    import GoodsDetail from "../goods/goods-detail/GoodsDetail";
    import GoodsList from "../goods/goods-list/GoodsList";
    
    export default function Router() {
      return (
        <BrowserRouter>
          <Routes>
            <Route path='/' element={<Home />}>
              <Route path='goods' element={<Goods />} >
                {/* 默认 子路由 ,在页面 路由为 /goods ,会展示该子路由 */}
                <Route index element={<GoodsList />}/>
    
                <Route path=":id" element={<GoodsDetail />}/>
              </Route>
    
              <Route path='customer' element={<Customer />} ></Route>
              <Route path="*" element={<NotFound />} /> 
            </Route>
    
          </Routes>
        </BrowserRouter>
      );
    }
    

    【7】通过配置实现路由管理

    • useRoutes可以讲数组对象形式的路由,直接在页面上使用。
    // 入口文件,src/index.tsx
    import React from "react";
    import ReactDOM from "react-dom";
    import { BrowserRouter } from "react-router-dom";
    import App from "./App";
    import "./index";
    
    
    ReactDOM.render((
      <BrowserRouter>
        <App />
      </BrowserRouter>
    ), document.getElementById("root"));
    
    // src/router/routes.tsx
    import React from "react";
    import { RouteObject } from "react-router-dom";
    import Home from "../home/Home";
    import Goods from "../goods/Goods";
    import Customer from "../customer/Customer";
    import NotFound from "../not-found/NotFound";
    import GoodsDetail from "../goods/goods-detail/GoodsDetail";
    import GoodsList from "../goods/goods-list/GoodsList";
    
    const routes: RouteObject[] = [
      {
        path: "/",
        element: <Home />,
        children: [
          {
            path: "/goods",
            element: <Goods />,
            children: [
              { index: true, element: <GoodsList /> },
              { path: ":id", element: <GoodsDetail /> }
            ]
          },
          {
            path: "/customer",
            element: <Customer />,
          },
          {
            path: "*",
            element: <NotFound />,
          },
        ]
      }
    ];
    
    export default routes;
    
    // src/App.tsx
    import React from "react";
    import { useRoutes } from "react-router-dom";
    import routes from "./router/routes";
    
    export default function App() {
    
      const element = useRoutes(routes);
      return (
        <>
          {element}
        </>
      );
    }
    
    
  • 相关阅读:
    oracle 11g完全彻底的卸载
    Windows添加.NET Framework 3.0 NetFx3 失败
    Crontab中的除号(slash)到底怎么用?
    Codeigniter文件上传类型不匹配错误
    Mac下遇到 'reading initial communication packet’ 问题
    使用PHP的正则抓取页面中的网址
    关于Advertising Campaign
    20个Linux服务器安全强化建议(三)
    20个Linux服务器安全强化建议(二)
    20个Linux服务器安全强化建议(一)
  • 原文地址:https://www.cnblogs.com/huayang1995/p/15752519.html
Copyright © 2011-2022 走看看