20230603----重返学习-react路由导航-路由传参-react-router-dom的V6版本

day-084-eighty-four-20230603-react路由导航-路由传参-react-router-dom的V6版本

react路由导航

编码式导航

  • 编码式导航:基于JavaScript实现路由的跳转。

  • 编码式导航:基于JavaScript实现路由的跳转。实际上是基于props中history对象中的相关方法实现路由跳转的。

  • 在路由当中:

    • 受控组件:受路由管控的组件,也就是基于Route组件进行路由匹配而渲染的组件。
    • 非受控组件:不是基于Route组件匹配渲染的组件。
  • 在react-router-dom的V5版本中:

    • 如果是受控组件,则路由内容,会给每个组件传递三个属性:

      • history 提供了路由跳转的方式。

        • push:跳转路由新增历史记录
        • replace:跳转路由与替换当前的历史记录
        • go:跳转到历史记录中指定位置
        • goBack:回退一步 -> go(-1);
        • goForward:前进一步 -> go(1);
      • location:记录当前路由的信息。

        • pathname:当前路由地址。
        • search:当前路由的问号传参信息。
        • state:当前路由的隐式传参信息。
      • match:记录当前路由匹配的规则与匹配记录。

        • params:存储匹配的路径参数信息。
    • 如果是非受控组件,默认不会传递这三个属性。

      • 这样就有一个问题:在非受控组件中,如何实现编程式导航?
        1. 基于路由内部提供的withRouter()高阶组件,把非受控组件变为受控组件

          • 或者说让非受控组件,也具备这三个属性信息,可适用于任何类型的组件
          import { withRouter } from "react-router-dom";
          const CommonMenu = function CommonMenu(props) {
            console.log(`CommonMenu-props`, props);
            return 
          } export default withRouter(CommonMenu);
        2. 基于路由提供的useHistory()/useLocation()/useParams()/useRouteMatch()等Hook函数,在函数组件中获取对应的信息!

          • useHistory() -> history对象
          • useLocation() -> location对象
          • useRouteMatch() -> match对象
          • useParams() -> 获取基于路径传参的信息。
        • 以上知识,必须有一个前提:所处理的组件,不管是受控还是非受控,必须都在HashRouter()/BrowserRouter()等Router的内部!

路由传参

  • 路由跳转传参的方式:
    • 例如从A组件跳转到B组件,需要给B组件传递一些参数信息。
      1. 基于问号传参传递信息。

        • 传递的信息在URL地址栏中可以看见(明文)。
          • 不安全有长度限制
        • 传递的信息都要变为urlencoded格式字符串,接收的时候也需要处理这样的字符串。
          • 可以基于qs库或者new URLSearchParams()处理。
        • 跳转后的目标组件进行刷新操作,因为传递的信息在地址栏中有,所以依然可以获取问号传参信息
      2. 基于隐式传参传递信息。

        • 传递的信息URL地址栏中看不见。
          • 不丑安全没有长度限制
        • 可以传递任何格式的数据。
        • 跳转后的目标组件进行刷新操作,因为地址栏没有传递的信息,那么之前传递的信息就消失了。
      3. 基于路径参数传递信息,把传参信息作为地址的一部分

        • 问号传参一样,也是要把传递的信息放在URL地址栏中,所以相关特点和问号传参几乎一致。
          • 只不过这种模式看上去比问号传参美观一些。
        • 步骤:
          • 第一步:修改路由匹配的规则。
            • path: '/home/message' 旧写法。
            • path: '/home/message/:lx?/:name?' 新写法。
              • : 说明是传递的参数。
              • ? 可传可不传。
          • 第二步:跳转的时候,把需要传递的值,作为地址的一部分;接收信息的时候,基于 match.params/useParams() 处理即可!

对问号传参的urlencoded格式字符串信息处理

路由懒加载

  • 默认情况下,我们会把所有组件的代码全部打包到一个js文件中-即主js文件。这样当页面第一次渲染的时候,需要从服务器获取这个主js文件才能执行,但是因为其文件过大,需要加载很长时间,在此期间内,页面呈现白屏。

    • 为了加快页面第一次渲染的速度,我们只把默认需要展示的组件打包到主js文件中,让主js文件小一些,其余组件的代码单独打包到别的js文件中,刚开始加载页面的时候不加载这些代码。
      • 当基于路由切换,需要加载某个组件的时候,再动态的从服务器获取对应的js文件或对应的代码,进行渲染!
      • 我们把以上这种优化手段,称之为路由懒加载。
        • 这个是前端必做的性能优化之一。
  • 路由懒加载步骤:

    1. 基于React.lazy、ES6中的import函数、/webpackChunkName:‘home’/,保证webpack打包后的时候,可以把各个组件代码打包到不同的js文件中!页面渲染的时候,最开始只加载主js文件。
      • 路由切换时,会再加载其它基于webpackChunkName的的js文件。
    2. 基于React.Suspense来处理动态加载的组件或异步组件,只有这样才能把异步组件中加载出来。
      • fallback: 在异步组件没有渲染出来之前,先展示fallback中的信息,异步组件渲染出来后,fallback中的信息就会销毁!
  • 在jsx文件及js代码中,使用src引入文件如图片这类需要使用文件地址时,要先用ES6把相对路径的文件导入进来再引用。或者使用绝对路径。

  • 在css或less时,使用图片这类需要使用文件地址时,是可以直接使用相对路径的。

组件封装-loading

react-router-dom的V6版本

react路由V6版本-基础版文件结构

  • 文件结构
    • React阶段/day0603_router6/src/index.jsx
    • React阶段/day0603_router6/src/App.jsx 构建一级路由
    • React阶段/day0603_router6/src/layout 布局类组件放置处,实际上这里放的大多为一级路由对应的组件。
      1. 因为布局类的文件大多是一级路由对应的组件。
      2. 个人2023年感觉很多项目是这样拆分的,这样可以让文件更明确些。
        • 个人做过的项目和参考的项目大多是这样布置的。
        • 理论上,也都可以全部放在views文件夹下。
      3. 放在这里,也可以让项目层级减少一层。
      4. 这个理论上可以凭个人喜好来。
      • React阶段/day0603_router6/src/layout/BasicLayout.jsx
      • React阶段/day0603_router6/src/layout/Error.jsx
      • React阶段/day0603_router6/src/layout/UserLayout.jsx
    • React阶段/day0603_router6/src/views 页面组件,一般是二级及以下的业务组件。
      • React阶段/day0603_router6/src/views/home 二级路由组件-Home.jsx下的三级路由组件。
        • React阶段/day0603_router6/src/views/home/Message.jsx
        • React阶段/day0603_router6/src/views/home/Watch.jsx
        • React阶段/day0603_router6/src/views/home/Worker.jsx
      • React阶段/day0603_router6/src/views/Category.jsx
      • React阶段/day0603_router6/src/views/Home.jsx
      • React阶段/day0603_router6/src/views/Login.jsx
      • React阶段/day0603_router6/src/views/Personal.jsx
      • React阶段/day0603_router6/src/views/Register.jsx

react路由V6版本-基础版路由代码

  • 文件结构
    • React阶段/day0603_router6/src/index.jsx

      import React from "react";
      import ReactDOM from "react-dom/client";
      /* ANTD */
      import { ConfigProvider } from "antd";
      import zhCN from "antd/locale/zh_CN";
      /* 组件&样式 */
      import "./index.less";
      import App from "./App";
      
      const root = ReactDOM.createRoot(document.getElementById("root"));
      root.render(
        
          
        
      );
      
    • React阶段/day0603_router6/src/App.jsx 主视图文件,构建一级路由。

      import React from "react";
      
      // 1. 引入HashRouter, Routes, Route, Navigate等react-router-dom提供的组件。引入HashRouter用于把组件包起来,Routes用于设置路由信息组-把多条路由信息组合成一组以便只渲染一个路由视图,Route用于设置单条路由信息,Navigate用于与Route配合起来设置重定向。
      import { HashRouter, Routes, Route, Navigate } from "react-router-dom";
      
      // 2. 引入路由需要用到的业务视图组件。
      import BasicLayout from "./layout/BasicLayout";
      import UserLayout from "./layout/UserLayout";
      import Error from "./layout/Error";
      import Login from "./views/Login";
      import Register from "./views/Register";
      import Home from "./views/Home";
      import Personal from "./views/Personal";
      import Category from "./views/Category";
      import Watch from "./views/home/Watch";
      import Worker from "./views/home/Worker";
      import Message from "./views/home/Message";
      
      const App = function App() {
        // 3. 构建路由。
        return (
          
            
              }>
                } />
                }>
                  } />
                  } />
                  } />
                  } />
                
                } />
                } />
              
              }>
                } />
                } />
                } />
              
              } />
              } />
            
          
        );
      };
      export default App;
      
    • React阶段/day0603_router6/src/layout

      • React阶段/day0603_router6/src/layout/BasicLayout.jsx 一级路由组件。

        import { useState } from "react"
        import { Menu, Button } from "antd"
        import { HomeOutlined, ClusterOutlined, UserOutlined, MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons'
        import styled from "styled-components"
        import logo from "@/assets/images/logo.svg"
        import avatar from "@/assets/images/touxiang.png"
        import { Outlet } from "react-router-dom"
        
        /* 组件样式 */
        const BasicLayoutStyle = styled.div`
            height: 100%;
            overflow: hidden;
        
            .header{
                box-sizing: border-box;
                padding: 0 15px;
                height: 48px;
                background: #001529;
                display: flex;
                justify-content: space-between;
                align-items: center;
        
                .logo,
                .info{
                    line-height: 48px;
                    font-size: 18px;
                    color: #FFF;
                    display: flex;
                    align-items: center;
        
                    img{
                        margin-right: 10px;
                        width: 35px;
                        height: 35px;
                    }
                }
        
                .info{
                    font-size: 14px;
        
                    img{
                        width: 30px;
                        height: 30px;
                    }
                }
            }
        
            .content{
                height: calc(100% - 48px);
                display: flex;
        
                .menu-box{
                    height: 100%;
                    background: #001529;
        
                    .ant-btn{
                        margin-left: 4px;
                        background: transparent;
                        box-shadow: none;
                    }
        
                    .ant-menu-item{
                        padding: 0 24px;
                    }
        
                    .ant-menu-inline-collapsed{
                        .ant-menu-item{
                            padding: 0 28px;
                        }
                    }
                }
        
                .view-box{
                    box-sizing: border-box;
                    padding: 15px;
                    height: 100%;
                    flex-grow: 1;
        
                    .component{
                        height: 100%;
                        overflow-y: auto;
                        overflow-x: hidden;
                        background: #FFF;
                    }
                }
            }
        `
        
        const BasicLayout = function BasicLayout() {
            // 左侧Menu的数据
            const menuItem = [{
                key: 'home',
                label: '控制面板',
                icon: 
            }, {
                key: 'category',
                label: '分类管理',
                icon: 
            }, {
                key: 'personal',
                label: '个人中心',
                icon: 
            }]
        
            // 定义状态
            let [collapsed, setCollapsed] = useState(false)
        
            return 
                

        Ant Design

        海贼王-路飞

        {/* 主页的二级路由 */}
        } export default BasicLayout
      • React阶段/day0603_router6/src/layout/Error.jsx 一级路由组件。

        import React from "react";
        import { Button, Empty } from "antd";
        import styled from "styled-components";
        
        /* 组件的样式 */
        const ErrorStyle = styled.div`
          height: 100%;
          overflow: hidden;
        
          .ant-empty {
            position: relative;
            top: 100px;
          }
        `;
        
        const Error = function Error() {
          return (
            
              很遗憾,您访问的页面不存在!}>
                
              
            
          );
        };
        export default Error;
        
      • React阶段/day0603_router6/src/layout/UserLayout.jsx 一级路由组件。

        import React from "react";
        import { Tabs } from "antd";
        import styled from "styled-components";
        import backgroundImg from "@/assets/images/background.svg";
        import logo from "@/assets/images/logo.svg";
        import { Outlet } from "react-router-dom";
        
        /* 组件样式 */
        const UserLayoutStyle = styled.div`
          position: relative;
          height: 100%;
          background: url(${backgroundImg}) no-repeat;
          background-size: 100%;
        
          .content {
            position: absolute;
            top: 100px;
            left: 50%;
            margin-left: -165px;
            width: 330px;
          }
        
          .header {
            .title {
              display: flex;
              justify-content: center;
              align-items: center;
              line-height: 44px;
              font-size: 33px;
              font-weight: normal;
        
              img {
                margin-right: 10px;
                width: 44px;
                height: 44px;
              }
            }
        
            .subtitle {
              margin: 12px 0 40px 0;
              text-align: center;
              font-size: 14px;
              color: rgba(0, 0, 0, 0.45);
            }
          }
        
          .ant-tabs {
            margin-bottom: 10px;
        
            .ant-tabs-nav {
              &:before {
                border-bottom-color: #ddd;
              }
            }
        
            .ant-tabs-tab {
              padding: 0 10px;
              font-size: 16px;
              line-height: 40px;
            }
          }
        `;
        
        const UserLayout = function UserLayout() {
          // Tab页卡的数据
          const tabItem = [
            {
              label: `用户登录`,
              key: "login",
            },
            {
              label: `用户注册`,
              key: "register",
            },
          ];
        
          return (
            
              

        Ant Design

        Ant Design 是西湖区最具影响力的 Web 设计规范

        {/* 登录/注册二级路由的位置 */}
        ); }; export default UserLayout;
    • React阶段/day0603_router6/src/views 页面组件,一般是二级及以下的业务组件。

      • React阶段/day0603_router6/src/views/home 二级路由组件-Home.jsx下的三级路由组件。

        • React阶段/day0603_router6/src/views/home/Message.jsx

          import React from "react";
          const Message = function Message() {
            return 
          控制面板 - 消息中心
          ; }; export default Message;
        • React阶段/day0603_router6/src/views/home/Watch.jsx

          import React from "react";
          const Watch = function Watch() {
            return 
          控制面板 - 数据监控
          ; }; export default Watch;
        • React阶段/day0603_router6/src/views/home/Worker.jsx

          import React from "react";
          const Worker = function Worker() {
            return 
          控制面板 - 工作台
          ; }; export default Worker;
      • React阶段/day0603_router6/src/views/Category.jsx

        import React from "react";
        const Category = function Category() {
          return 
        分类管理的内容
        ; }; export default Category;
      • React阶段/day0603_router6/src/views/Home.jsx 二级路由组件。

        import React from "react";
        import styled from "styled-components";
        import { NavLink, Outlet } from "react-router-dom";
        
        /* 组件样式 */
        const HomeStyle = styled.div`
          padding: 10px;
        
          .nav-box {
            display: flex;
            border-bottom: 1px solid #eee;
        
            a {
              padding: 0 20px;
              line-height: 40px;
              font-size: 15px;
              color: #000;
        
              &.active {
                color: #1677ff;
                font-size: 16px;
              }
            }
          }
        `;
        
        const Home = function Home() {
          return (
            
              
              {/* 首页的三级路由 */}
              
            
          );
        };
        export default Home;
        
      • React阶段/day0603_router6/src/views/Login.jsx 二级路由组件。

        import React from "react";
        import { Form, Input, Checkbox, Button } from "antd";
        import { UserOutlined, LockOutlined } from "@ant-design/icons";
        import styled from "styled-components";
        
        /* 组件的样式 */
        const LoginStyle = styled.div`
          .remember {
            display: flex;
            justify-content: space-between;
            align-items: center;
        
            a {
              font-size: 14px;
              color: #1890ff;
            }
          }
        
          .submit {
            width: 100%;
          }
        `;
        
        const Login = function Login() {
          return (
            
              
        } /> } />
        记住账号密码 忘记密码?
        ); }; export default Login;
      • React阶段/day0603_router6/src/views/Personal.jsx

        import React from "react";
        const Personal = function Personal() {
          return 
        个人中心的内容
        ; }; export default Personal;
      • React阶段/day0603_router6/src/views/Register.jsx

        import React from "react";
        import { Form, Input, Button } from "antd";
        import { LockOutlined, PhoneOutlined } from "@ant-design/icons";
        import styled from "styled-components";
        
        /* 组件的样式 */
        const RegisterStyle = styled.div`
          .submit {
            width: 100%;
          }
        
          .code-box {
            display: flex;
            justify-content: space-between;
            align-items: center;
        
            .ant-form-item {
              &:nth-child(1) {
                margin-right: 10px;
              }
            }
          }
        `;
        
        const Register = function Register() {
          return (
            
              
        } />
        } />
        ); }; export default Register;

react路由V6版本-基础版构建步骤

  1. 在主视图文件里引入构建一级路由。

    1. 引入HashRouter, Routes, Route, Navigate等react-router-dom提供的组件。
      • HashRouter用于把组件包起来。
      • Routes用于设置路由信息组-把多条路由信息组合成一组以便只渲染一个路由视图。
      • Route用于设置单条路由信息。
      • Navigate用于与Route配合起来设置重定向。
    2. 引入路由需要用到的业务视图组件。
    3. 使用HashRouter, Routes, Route, Navigate等及业务视图组件来构建路由。
      • 所有需要用到路由信息的,都要用这个组件包起来。

      • 包裹一组路由信息。

        1. 内部只能放标签,放其它标签会报错。
        2. 所有级别的路由匹配规则路由表都写在一起。
      • 用来设置一条路由信息。

        1. 内部可以嵌套

        2. 默认匹配规则类似于精准匹配。

        3. 被嵌套的标签就是子级路由。

        4. 子级路由可以省略父级路由地址。

          • 不过子级路由以/开头,就会被认为是绝对路径。
          • 子级路由不以/开头,那么其前方就会自动添加上父级路由的地址。
        5. 要渲染的组件用element属性来设置,但element属性的值必须是一个组件标签的格式,而不能只是一个函数变量。

          } />//一个组件标签的格式,是对的。
          
          //一个函数变量,是错的。
          
        import React from "react";
        
        // 1. 引入HashRouter, Routes, Route, Navigate等react-router-dom提供的组件。引入HashRouter用于把组件包起来,Routes用于设置路由信息组-把多条路由信息组合成一组以便只渲染一个路由视图,Route用于设置单条路由信息,Navigate用于与Route配合起来设置重定向。
        import { HashRouter, Routes, Route, Navigate } from "react-router-dom";
        
        // 2. 引入路由需要用到的业务视图组件。
        import BasicLayout from "./layout/BasicLayout";
        import UserLayout from "./layout/UserLayout";
        import Error from "./layout/Error";
        import Login from "./views/Login";
        import Register from "./views/Register";
        import Home from "./views/Home";
        import Personal from "./views/Personal";
        import Category from "./views/Category";
        import Watch from "./views/home/Watch";
        import Worker from "./views/home/Worker";
        import Message from "./views/home/Message";
        
        const App = function App() {
          // 3. 构建路由。
          return (
            
              
                }>
                  } />
                  }>
                    } />
                    } />
                    } />
                    } />
                  
                  } />
                  } />
                
                }>
                  } />
                  } />
                  } />
                
                } />
                } />
              
            
          );
        };
        export default App;
        
      • } /> 用于设置路由跳转。

  2. 在父级路由匹配组件的指定位置,基于组件把子级路由匹配的内容进行渲染!

    // 1. 引入Outlet组件。
    import { Outlet } from "react-router-dom"
    
    {/* 2. 在父级路由匹配组件的指定位置,基于`组件`把子级路由匹配的内容进行渲染! */}
    
    
    import { useState } from "react"
    import { Menu, Button } from "antd"
    import { HomeOutlined, ClusterOutlined, UserOutlined, MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons'
    import styled from "styled-components"
    import logo from "@/assets/images/logo.svg"
    import avatar from "@/assets/images/touxiang.png"
    
    // 1. 引入Outlet组件。
    import { Outlet } from "react-router-dom"
    
    /* 组件样式 */
    const BasicLayoutStyle = styled.div`
        height: 100%;
        overflow: hidden;
    
        .header{
            box-sizing: border-box;
            padding: 0 15px;
            height: 48px;
            background: #001529;
            display: flex;
            justify-content: space-between;
            align-items: center;
    
            .logo,
            .info{
                line-height: 48px;
                font-size: 18px;
                color: #FFF;
                display: flex;
                align-items: center;
    
                img{
                    margin-right: 10px;
                    width: 35px;
                    height: 35px;
                }
            }
    
            .info{
                font-size: 14px;
    
                img{
                    width: 30px;
                    height: 30px;
                }
            }
        }
    
        .content{
            height: calc(100% - 48px);
            display: flex;
    
            .menu-box{
                height: 100%;
                background: #001529;
    
                .ant-btn{
                    margin-left: 4px;
                    background: transparent;
                    box-shadow: none;
                }
    
                .ant-menu-item{
                    padding: 0 24px;
                }
    
                .ant-menu-inline-collapsed{
                    .ant-menu-item{
                        padding: 0 28px;
                    }
                }
            }
    
            .view-box{
                box-sizing: border-box;
                padding: 15px;
                height: 100%;
                flex-grow: 1;
    
                .component{
                    height: 100%;
                    overflow-y: auto;
                    overflow-x: hidden;
                    background: #FFF;
                }
            }
        }
    `
    
    const BasicLayout = function BasicLayout() {
        // 左侧Menu的数据
        const menuItem = [{
            key: 'home',
            label: '控制面板',
            icon: 
        }, {
            key: 'category',
            label: '分类管理',
            icon: 
        }, {
            key: 'personal',
            label: '个人中心',
            icon: 
        }]
    
        // 定义状态
        let [collapsed, setCollapsed] = useState(false)
    
        return 
            

    Ant Design

    海贼王-路飞

    {/* 主页的二级路由 */} {/* 2. 在父级路由匹配组件的指定位置,基于`组件`把子级路由匹配的内容进行渲染! */}
    } export default BasicLayout

与路由V5版本的区别

  • react-router-dom(V6)react-router-dom(V5)对比
  1. 都是基于HashRouter()BrowserRouter()来指定路由的模式,而且建议所有的组件都放在HashRouter()与BrowserRouter()这类Router中。

  2. V6版本中没有了,因为不需要了,其内部自己做了类似于的处理。

  3. V6中没有了,但是可以基于来代替它。

    • 在V5版本中,相当于特殊的,我们是基于它设置重定向的规则的。
    • 在V6版本中,是一个组件,渲染这个组件时会重定向到该组件的to属性指定的地址
      • } />
  4. V6中也是基于设置匹配规则,只不过都需要放在>中,而且在上设置的详细规则,和V5版本有很大的区别:

    • 无需在上设置exact属性用于进行精准匹配了,因为默认都是类似于精准匹配
    • path属性和之前一样,设置对应的匹配地址。
    • 匹配成功后需要渲染那个组件不再基于component属性处理,而是基于element属性渲染,而且也没有了render函数属性这样的配置,element渲染的内容需要写成这种格式!
      • 只能放

      • V5旧:

        import { HashRouter, BrowserRouter, Route, Switch, Redirect } from 'react-router-dom'
        import BasicLayout from "./layout/BasicLayout"
        import UserLayout from "./layout/UserLayout"
        import Error from "./layout/Error"
        
            
                
                
                
                
            
        
        //或
        
          
        
        
      • V6新:

        import { HashRouter, Routes, Route, Navigate } from "react-router-dom";
        
        import BasicLayout from "./layout/BasicLayout";
        import UserLayout from "./layout/UserLayout";
        import Error from "./layout/Error";
        
          
            }>
            }>
            } />
            } />
          
        
        //或
        
          
            }>
          
        
        
  5. V6有一个重大的变革:所有级别的路由匹配规则路由表都写在一起,而不再像V5一样,需要分散到指定组件的特定位置上,这样有利于路由的统一管理

    }>
    /* - 在`子级路由中`其path可以省略`父级路由的地址`
        - 但是也不要自己再加`/`
        - `path=""` 等价于 `path="/user"`
        - `path="login"`等价于 `path="/user/login"`
      - 如果路由地址是`/user/xxx`,首先和一级路由`/user`进行匹配了,渲染`UserLayout组件`后,进入`/user`的`子级路由`进行匹配;
        - 在`子级路由`中`一项项地进行匹配`,匹配成功,就把`子级路由`中`element属性指定的组件`,放在`UserLayout组件`中的`容器`中进行渲染!
        - 如果在`子级路由`中没有任何匹配的,则跳出这一级,继续向下匹配`与/user路由同级`的`其它的一级路由`! */
        } />
        } />
        } />
    
    
    • 子级路由中其path可以省略父级路由的地址

      • 但是也不要自己再加/
      • path="" 等价于 path="/user"
      • path="login"等价于 path="/user/login"
    • 如果路由地址是/user/xxx,首先和一级路由/user进行匹配了,渲染UserLayout组件后,进入/user子级路由进行匹配;

      • 子级路由一项项地进行匹配,匹配成功,就把子级路由element属性指定的组件,放在UserLayout组件中的容器中进行渲染!
      • 如果在子级路由中没有任何匹配的,则跳出这一级,继续向下匹配与/user路由同级其它的一级路由
    • 但是需要在上级路由匹配组件的指定位置,基于把下级路由匹配的内容进行渲染!

进阶参考

你可能感兴趣的:(react.js,重返学习,React,react.js,javascript,学习)