V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
wuchangming89
V2EX  ›  JavaScript

分享:实现动态加载 reducer

  •  
  •   wuchangming89 · 2017-10-17 02:11:43 +08:00 · 3362 次点击
    这是一个创建于 2619 天前的主题,其中的信息可能已经有所发展或是发生改变。

    lazy-reducer

    动态加载 reducer

    项目地址: https://github.com/KeyFE/lazy-reducer

    npm version

    Install

    npm install --save lazy-reducer
    

    只有 3 个 API

    配置

    lazyReducerEnhancer

    使用前只需简单配置 store,添加一个 enhancer 即可

    import { lazyReducerEnhancer } from 'lazy-reducer';
    
    const rootReducerObj = {
        nameA: reducerA,
        nameB: reducerB
    };
    const store = createStore(combineReducers(rootReducerObj), {}, lazyReducerEnhancer(rootReducerObj));
    

    用法

    1.<LazyReducer /> Componnet 用法

    import { LazyReducer } from 'lazy-reducer';
    
    <LazyReducer
        reducer={{
            nameX: someReducer
        }}
    >
        <AnyComponent />
    </LazyReducer>
    

    2.withLazyReducer 高阶组件用法

    import { withLazyReducer } from 'lazy-reducer';
    
    class Comp extends Component {
        render() {
            <div>i am a Component wrapped by lazy reducer !</div>;
        }
    }
    
    export default withLazyReducer({
        nameX: someReducer
    })(Comp);
    

    使用注解方式

    import { withLazyReducer } from 'lazy-reducer';
    
    @withLazyReducer({
        nameX: someReducer
    })
    class Comp extends Component {
        render() {
            <div>i am a Component wrapped by lazy reducer !</div>;
        }
    }
    
    export default Comp;
    

    示例

    示例地址: ://github.com/KeyFE/lazy-reducer/tree/master/example

    6 条回复    2017-10-19 18:51:00 +08:00
    doublleft
        1
    doublleft  
       2017-10-17 13:59:10 +08:00
    和 requre.ensure 实现的有啥区别,我是觉得放在 router 里做不会影响业务写法,不想用的时候也可以随时切回去
    wuchangming89
        2
    wuchangming89  
    OP
       2017-10-17 14:44:22 +08:00
    @doublleft , requre.ensure 只是做了代码分块。一般我们用到 redux 的时候都是一开始就初始化好整个 reducer 的结构。所以就算把某个 reducer 代码做了分块,也是一开始就需要加载做初始化。并不能减少首屏加载的代码量。

    如:
    路由 /a/xx 只用到了 reducerA
    路由 /b/xx 只用到了 reducerB

    一般的做法,必须一开始就初始化所有 reducer。
    const rootReducer = combineReducers({
    reducerA,
    reducerB
    })

    但如果异步去加载 reducer,就可以等真正需要用到的时候再去载入相应的 reducer。
    对比较大的项目来说应该可以减少一定的首屏时间。
    doublleft
        3
    doublleft  
       2017-10-17 15:41:03 +08:00
    @wuchangming89 require.ensure 可以做到异步拉代码啊,只要是有个异步的前提条件就行。一般是在 ReactRouter 的 getComponent 时候,会主动拉这个 Chunk 文件的。
    wuchangming89
        4
    wuchangming89  
    OP
       2017-10-17 16:27:33 +08:00
    @doublleft ,是可以 require.ensure 异步拉代码。但因为初始化 store 的时候就用到所有的 reducer,已经决定了你必须一开始就去把分块到另一个文件中的 reducer 加载回来。不能等到真正要用到某个 reducer 再去异步拉,加载相应的 reducer。require.ensure 只是把代码分到了另一个文件,不能决定那个文件是什么会被拉取。
    doublleft
        5
    doublleft  
       2017-10-19 11:07:39 +08:00
    @wuchangming89 初始化 Store 的时候也可以不用全部的 reducer,只初始化基础库,router getComponent 时候再异步拉 chunk,然后 replaceReducer,还可以隔离环境~
    wuchangming89
        6
    wuchangming89  
    OP
       2017-10-19 18:51:00 +08:00   ❤️ 1
    @doublleft,你说这个是可以的。嗯,这里其实就是简单封装了下你说的这种方式。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5163 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 09:32 · PVG 17:32 · LAX 01:32 · JFK 04:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.