• React进阶篇(1) -- react-router4模块化


    本篇内容:

    • 单一的路由无嵌套
    • 多层嵌套路由
    • 获取路径中的参数
    • 按需加载

    单一的路由无嵌套

    routers.js

    import Home from 'components/Home';
    import News from 'components/News';
    import User from 'components/User';
    import My from 'components/My';
    
    let routes=[
        {
            path:'/',
            component:Home ,
            exact:true
        },
        {
            path:'/news',
            component:News ,
        },
        {
            path:'/user',
            component:User 
        },
        {
            path:'/my',
            component:My 
        },
    ]
    export default routes;
    

    App.jsx

    import React, { Component } from 'react';
    import { HashRouter as Router, Switch, Route } from "react-router-dom";
    import routes from '../routers/index';
    class App extends Component {
      render() {
        return (
            <Router>
                <div>
                    <Switch>
                        //主要逻辑在这里
                        {
                            routes.map((item, i) => {
                                if(item.exact){
                                    return <Route exact path={item.path} component={item.component}  key={i}/>
                                }else{
                                    return <Route path={item.path} component={item.component}  key={i}/>
                                }
                            }) 
                        }
                    </Switch> 
                </div>
            </Router>
        );
      }
    }
    

    多层嵌套路由

    let routes=[
        {
            path:'/hear',
            component:Hear,
            exact:true,
            description:"听",
            subs:[
                {
                    path:'/hear/',
                    component:HearIndex,
                    description:"听-首页" 
                },
                {
                    path:'/hear/book',
                    component:HearBook,
                    description:"听-课文" 
                },
            ]
        },
        {
            path:'/speak',
            component:Speak,
            exact:true,
            description:"说",
            subs:[
                {
                    path:'/speak/',
                    component:CN,
                    description:"说-汉语" 
                },
                {
                    path:'/speak/english',
                    component:English,
                    description:"说-英语" 
                },
            ]
        },
        {
            path:'/read',
            component:Read,
            exact:true,
            description:"读",
            subs:[
                {
                    path:'/read/',
                    component:ReadBook,
                    description:"读-课文" 
                },
                {
                    path:'/read/newspaper',
                    component:ReadNews,
                    description:"读-报纸" 
                },
            ]
        },
        {
            path:'/writ',
            component:Writ,
            exact:true,
            description:"写"
        }
    ]
    export default routes;
    

    App.jsx

    {
        routes.map((item, i) => {
            if (item.exact) {
                //官方固定格式
                return <Route exact path={item.path} key={i} render={ props => (<item.component {...props} routes={item.subs}/>) />
            }
            else {
                return <Route path={item.path} key={i} render={ props => (<item.component {...props}  routes={item.subs}/>)} />
            }
        })
    }
    
    

    //step 2,在对应的组件中再次遍历

    {
        this.props.routes.map((item, i) => {
            return <Route exact path={item.path}
            component= {item.component}
            key={i}/>
        })
    }
    

    跳转

    this.props.history.push(`/about/type/${id}`)
    this.props.history.replace(...)
    

    注意:

    不能在子组件中直接获取,需要从父级传入之后用props获取;

    跳转时,如果还有事件未结束,则容易报错!

    如:

    <LoginCom TIMEID={TIMEID} {...this.props}/>
    

    获取路径参数

    获取对应的params

    this.props.match.params.id
    

    获取?后面对应的值

    const getQueryString = (str,name) => {
        let result = str.match(new RegExp("[?&]" + name + "=([^&]+)", "i"));
        if (result == null || result.length < 1) {
            return "";
        }
        return decodeURI(result[1], "utf-8");
    }
    

    如:http://localhost:3000/#/textbook/bishun?val=看

    console.log(getQueryString(this.props.location.search,'val'));
    

    按需加载

    感觉这种方式最简单:

    基于 webpack, babel-plugin-syntax-dynamic-import, 和 react-loadable;

    主要是利用了react-loadable这个高级组件,他是专门用来异步加载(也可以预加载)组件的。

    cnpm i -S react-loadable @babel/plugin-syntax-dynamic-import
    

    .babelrc

    {
       “ presets ”:[ “ @ babel / react ” ],
       “ plugins ”:[ “ @ babel / plugin-syntax-dynamic-import ” ]
    }
    

    routers.js变化

    import Loadable from 'react-loadable';
    import DelayLoading from './DelayLoading';
    
    const Home= Loadable({loader: () => import('../components/Home'), loading : DelayLoading,delay:3000})
    const Login= Loadable({loader: () => import('../components/Login'), loading : DelayLoading,delay:3000})
    

    打包文件情况对比:

    首屏加载情况对比:

    参考文档:

    https://reacttraining.com/react-router/web/example/route-config

    https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/guides/code-splitting.md

    https://github.com/jamiebuilds/react-loadable

    可参考其他文章:https://www.cnblogs.com/alan2kat/p/7754846.html

  • 相关阅读:
    操作系统概述
    18 文本处理
    17 正则表达式(重点)
    16 归档和备份
    15 查找文件
    博客园图片折叠
    EF6学习笔记十五:调试EF框架源码
    EF6学习笔记十四:上下文管理
    Sqlserver和LocalDB创建数据库时默认字符集不一样
    EF6学习笔记十三:基础知识完结,零碎问题补缺
  • 原文地址:https://www.cnblogs.com/adoctors/p/10181242.html
Copyright © 2020-2023  润新知