zoukankan      html  css  js  c++  java
  • React:redux+router4搭建应用骨架

    可能是短期内关于react的对后一篇笔记。假设读者对redux和router4有基本了解。

    缘由:

    现在网上很多关于react+redux的文章都是沿用传统的文件组织形式,即:

    |--components
    
    |--reducers
    
    |--actionTypes
    
    |--actions
    
    |--else

    这样的目录形式。这种形式的一个好处是:store中的状态一开始就是完整的,在按需加载的时候不需要特意更新root reducer和全局state树,只加载对应的视图即可。

    但是,笔者在学习《深入浅出react+redux》的时候,作者提出的文件组织形式是以组件为单元组织app的文件结构,即:

    |--ComponentA
    
      |--action
    
      |--reducer
    
      |--View
    
      |--index.js
    
    |--ComponentB
    
      |--action
    
      |--reducer
    
      |--...

    此时app的store和root reducer在一开始只有公共部分,按需加载某个组件后,再对redux store和root reducer进行更新扩充。

    这种情况下,最关键的问题是:如何在每次按需加载后更新reducer和store。实践上分为两个阶段:

    1.异步加载组件。组件的reducer、view、state字段作为对外暴露的接口。

    2.加载完成后获取其reducer和state字段更新root reducer & redux store。

    《深入浅出》中作者给的方法是:

    1.用webpack的require.ensure分片组件,实现异步加载。

    2.借助store enhancer拓展一个store.reset方法,将新组件的reducer和state字段传进去,完成更新。

    然而现在要使用router4,怎么解决上面问题呢?

    我目前的方案是:

    1.异步加载使用Bundle组件(下面会给出其代码)。

    2.刷新store和root reducer仍然使用《深入浅出》作者给出的reset方法。

     ----------------------------------------------------------分割-----------------------------------------------

    我们现在已经会使用redux管理app状态。将state提取到全局store,并经由disptach方法派发action给root reducer 生成新的store state,而组件本身以观察者监听state变化。

    router4遵循组件即路由的思想,url匹配时由Route标签渲染我们的组件。所以本质上<Route>也是视图。与Redux毫无冲突。

    它们一个限制了我们app的数据流,一个控制我们视图的跳转。

    由于react-redux提供的Provider组件必须放到应用的最顶层以实现全局访问store,所以项目的最基本骨架是:

    |--Provider
        |--App
            |--Router
                |--RouteA
                    |--RouteA child
                |--RouteB
      //...

    在Router4中,我们往往用到的是Bundle组件来异步加载组件,我对它进行一些改写,以适应“按组件组织文件”的方式:

     1 import React from 'react';
     2 import PropTypes from 'prop-types';
     3 import {
     4   combineReducers
     5 } from 'redux';
     6 import store from './Store.js';
     7 class Bundle extends React.Component {
     8      constructor(props) {
     9         super(props);
    10         this.state = {
    11             mod: null
    12         };
    13         this.page=null;
    14     }
    15   componentWillMount() {
    16     // 加载初始状态
    17     this.load(this.props);
    18   }
    19 
    20   componentWillReceiveProps(nextProps) {
    21     if (nextProps.load !== this.props.load) {
    22       this.load(nextProps);
    23     }
    24   }
    25 
    26   load(props) {
    27     // 重置状态
    28     this.setState({
    29       mod: null
    30     });
    31     // 传入组件的组件
    32     props.load().then((mod) => {
    33       //...
    34       this.page=mod.Page;
    35       let {Page,stateKey,reducer,initialState} = mod;
    36       let state=store.getState();
    37       
    38       store.reset(combineReducers({...store._reducers,[stateKey]:reducer}),{...state,[stateKey]:initialState});
    39 
    40       this.setState({
    41         // handle both es imports and cjs
    42         mod: mod.Page.default ? mod.Page.default : mod
    43       });
    44     });
    45   }
    46 
    47   render() {
    48     // if state mode not undefined,The container will render children
    49     return this.state.mod ? this.props.children(this.page) : '加载中,请稍候...';
    50   }
    51 }
    52 
    53 Bundle.propTypes = {
    54   load: PropTypes.func,
    55   children: PropTypes.func
    56 };
    57 
    58 export default Bundle;
    View Code

    一个最基本的项目用到的依赖:

    react:

      提供了React、Component 帮助我们搭建视图层。

    redux:

      combineReducers帮我们生成Root Reducer

      createStore帮我们创建全局的store管理app状态。

      applyMiddleware 让我们调用中间件,增强dispatch方法

      compose帮我们组装store enhancer

    react-redux:

      Provider:让我们可以全局访问store

      connect:生成容器组件和store通信

    router4:

      Router、Route、Link等实现项目页面路由

    Bundle组件:

      配合Router4实现按需加载(用到import语法)

    工具明确了之后,我们开始构建应用。

    0.创建项目目录:全局的store.js、index.js、enhancer文件夹、组件文件夹等

    1.设计state树

    2.创建各个组件,写它的actionType、actionCreator、reducer,View、stateKey,在组件文件夹下index.js中引入,并将actionCreator、reducer、stateKey等导出。

    3.将公共部分的reducer引入root reducer文件中

    4.实现store,引入enhancer/reset.js,让其具备reset方法,以便按需加载时刷新reducer和状态。

    5.在index.js 和 App.js中搭建顶层结构,组织各个组件,设计各个页面的路由。

    //... 

     测试。

    build。

  • 相关阅读:
    什么是微服务架构?
    docker 安装 mongo he SCRAM_SHA_1 authentication mechanism requires libmongoc built with ENABLE_SSL
    好用的JsonView插件
    新建vmware虚拟机无法访问网络
    安装Docker到CentOS(YUM)
    CentOS7下安装MySQL5.7安装与配置
    mongodb 阿里云centos7安装
    JS数组
    前端基本知识
    JS算法
  • 原文地址:https://www.cnblogs.com/alan2kat/p/7824793.html
Copyright © 2011-2022 走看看