V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kimiler
V2EX  ›  程序员

求指教一个 redux 相关的问题,先谢过了

  •  
  •   kimiler · 2020-04-29 22:00:48 +08:00 · 1808 次点击
    这是一个创建于 1673 天前的主题,其中的信息可能已经有所发展或是发生改变。

    实际开发中,尤其是面向 c 端的用户,任何业务和用户操作我认为都应该包含这四种状态,loading,error,empty,success,为了简化 actionType 的分散性,所以就简单封装了一个 acitonModel

    /**
     * generator common actionModel 普通模型
     * @param {*} prefix 前缀,需要保证唯一性
     */
    export function generatorCommonActionModel(prefix) {
        const load_loading_action_type = prefix + common_load_loading;
        const load_empty_action_type = prefix + common_load_empty;
        const load_error_action_type = prefix + common_load_error;
        const load_success_action_type = prefix + common_load_success;
        const get_common_action_type = prefix + get_common;
        const reset_action_type = prefix + common_reset;
    
        return {
            prefix,
            load_loading_action_type,
            load_empty_action_type,
            load_error_action_type,
            load_success_action_type,
            get_common_action_type,
            reset_action_type,
            loadLoadingActionCreator: params => ({ type: load_loading_action_type, params }),
            loadEmptyActionCreator: params => ({ type: load_empty_action_type, params }),
            loadErrorActionCreator: params => ({ type: load_error_action_type, params }),
            loadSuccessActionCreator: (data, params) => ({ type: load_success_action_type, payload: { data, params } }),
            getCommonActionCreator: params => ({ type: get_common_action_type, params }),
            resetActionCreator: params => ({ type: reset_action_type, params })
        }
    }
    

    actionModel 根据 key 的唯一性来区分,使用的时候直接使用该函数可以快速生成对应的 action 模型,实际运用中也确实感受到了其方便性,但随之带来的问题就来了,就是 reducer 层,始终想不到该如何去优化处理,目前的做法

    /**
     * 统一处理 commonModelActions
     * @param {*} actionModel 需遵循 actionHelp 规范
     * @param {*} stateModel  需遵循 stateModel 中的 commonStateModel 数据模型规范
     * @param {*} action dispatch 出来的 action
     */
    export function reducerGeneratorCommonActionModel(actionModel, stateModel, action) {
        switch (action.type) {
            case actionModel.load_loading_action_type:
                return { ...stateModel, load_status: NetWorkComponent.LOAD_LOADING };
            case actionModel.load_empty_action_type:
                return { ...stateModel, load_status: NetWorkComponent.LOAD_EMPTY };
            case actionModel.load_error_action_type:
                return { ...stateModel, load_status: NetWorkComponent.LOAD_ERROR };
            case actionModel.load_success_action_type:
                return {
                    ...stateModel,
                    load_status: Array.isArray(action.payload.data) ? action.payload.data.length > 0 ? NetWorkComponent.LOAD_SUCCESS : NetWorkComponent.LOAD_EMPTY : NetWorkComponent.LOAD_SUCCESS,
                    data: action.payload.data
                };
            default:
                return stateModel;
        }
    }
    
    
    
    export default function (state = defaultState, action) {
        switch (action.type) {
            //当前城市广告位
            case goodShopAdvertisingCommonActionModel.load_loading_action_type:
            case goodShopAdvertisingCommonActionModel.load_empty_action_type:
            case goodShopAdvertisingCommonActionModel.load_error_action_type:
            case goodShopAdvertisingCommonActionModel.load_success_action_type:
                return { ...state, advertisings: reducerGeneratorCommonActionModel(goodShopAdvertisingCommonActionModel, state.advertisings, action) }
            //当前城市的榜单列表
            case goodShopRankingShopCommonActionModel.load_loading_action_type:
            case goodShopRankingShopCommonActionModel.load_empty_action_type:
            case goodShopRankingShopCommonActionModel.load_error_action_type:
            case goodShopRankingShopCommonActionModel.load_success_action_type:
                return { ...state, rankingShops: reducerGeneratorCommonActionModel(goodShopRankingShopCommonActionModel, state.rankingShops, action) }
            //当前城市的爆品秒杀商品列表
            case goodShopSeckillCommodityCommonActionModel.load_loading_action_type:
            case goodShopSeckillCommodityCommonActionModel.load_empty_action_type:
            case goodShopSeckillCommodityCommonActionModel.load_error_action_type:
            case goodShopSeckillCommodityCommonActionModel.load_success_action_type:
                return { ...state, seckillCommoditys: reducerGeneratorCommonActionModel(goodShopSeckillCommodityCommonActionModel, state.seckillCommoditys, action) }
            //附近的商户
            case goodShopNearbyShopListPagingActionModel.load_loading_action_type:
            case goodShopNearbyShopListPagingActionModel.load_empty_action_type:
            case goodShopNearbyShopListPagingActionModel.load_error_action_type:
            case goodShopNearbyShopListPagingActionModel.load_more_loading_action_type:
            case goodShopNearbyShopListPagingActionModel.load_more_empty_action_type:
            case goodShopNearbyShopListPagingActionModel.load_more_error_action_type:
            case goodShopNearbyShopListPagingActionModel.load_success_action_type:
                return { ...state, nearbyShops: reducerGeneratorListPagingActionModel(goodShopNearbyShopListPagingActionModel, state.nearbyShops, action) }
            //推荐的商户
            case goodShopRecommendShopCommonActionModel.load_loading_action_type:
            case goodShopRecommendShopCommonActionModel.load_empty_action_type:
            case goodShopRecommendShopCommonActionModel.load_error_action_type:
            case goodShopRecommendShopCommonActionModel.load_success_action_type:
                return { ...state, recommendShops: reducerGeneratorCommonActionModel(goodShopRecommendShopCommonActionModel, state.recommendShops, action) }
            //人气商圈的商户
            case goodShopHotShopListPagingActionModel.load_loading_action_type:
            case goodShopHotShopListPagingActionModel.load_empty_action_type:
            case goodShopHotShopListPagingActionModel.load_error_action_type:
            case goodShopHotShopListPagingActionModel.load_more_loading_action_type:
            case goodShopHotShopListPagingActionModel.load_more_empty_action_type:
            case goodShopHotShopListPagingActionModel.load_more_error_action_type:
            case goodShopHotShopListPagingActionModel.load_success_action_type:
                return { ...state, hotShops: reducerGeneratorListPagingActionModel(goodShopHotShopListPagingActionModel, state.hotShops, action) };
            //人气商圈栏目分类
            case goodShopHotShopClassifyCommonActionModel.load_loading_action_type:
            case goodShopHotShopClassifyCommonActionModel.load_empty_action_type:
            case goodShopHotShopClassifyCommonActionModel.load_error_action_type:
            case goodShopHotShopClassifyCommonActionModel.load_success_action_type:
                return { ...state, hotShopsClassify: reducerGeneratorCommonActionModel(goodShopHotShopClassifyCommonActionModel, state.hotShopsClassify, action) };
            //榜单详情
            case goodShopRankingShopDetailCommonActionModel.load_loading_action_type:
            case goodShopRankingShopDetailCommonActionModel.load_empty_action_type:
            case goodShopRankingShopDetailCommonActionModel.load_error_action_type:
            case goodShopRankingShopDetailCommonActionModel.load_success_action_type:
                return { ...state, rankingDetails: reducerMergeGeneratorCommonActionModel(goodShopRankingShopDetailCommonActionModel, state.rankingDetails, action) }
            //支持的城市列表
            case goodShopCitysCommonActionModel.load_loading_action_type:
            case goodShopCitysCommonActionModel.load_empty_action_type:
            case goodShopCitysCommonActionModel.load_error_action_type:
            case goodShopCitysCommonActionModel.load_success_action_type:
                return { ...state, citys: reducerGeneratorCommonActionModel(goodShopCitysCommonActionModel, 
    

    感觉这样去写,反而更累了,所以想问下 v 友门,这块要如何去设计和优化啊,再次感谢

    13 条回复    2020-04-30 15:03:30 +08:00
    jigi330
        1
    jigi330  
       2020-04-29 22:48:59 +08:00
    代码太长不想看了,感觉是根据 action 的不同的 type 去加载不同的 reducer 。
    我觉得应该可以用元编程去搞定,把你的具体的函数用 `注解` 去 Reflect.defineMetadata,然后用的时候,根据 action 的 type 用 Reflect.getMetadata 去遍历,找到对应的函数,执行它。
    KuroNekoFan
        2
    KuroNekoFan  
       2020-04-29 23:26:22 +08:00 via iPhone
    我有点好奇为什么一个 ui 状态会用 redux 来控制
    yazoox
        3
    yazoox  
       2020-04-29 23:30:18 +08:00 via Android
    你是觉得,switch case 太多了么?做个 map 或者 table 映射一下。速度快,写起来也不麻烦。
    p.s 代码太长了…… 手机看不清楚
    MintZX
        4
    MintZX  
       2020-04-29 23:38:31 +08:00 via iPhone
    每个不同种类的 reducer 拿出来单独做一个文件然后用 combine


    命名遵循一种方式,camelcase 或者 underscore 。不建议混用。

    试试 redux toolkit
    wd
        5
    wd  
       2020-04-30 06:51:48 +08:00 via iPhone
    没仔细看,但是第一段代码好像是写了一大堆代码只是为了名字短一点?哪为啥不直接取一个短名字...
    zhw2590582
        6
    zhw2590582  
       2020-04-30 08:22:43 +08:00
    好久没看过这种长命名的变量,读起来有点慌
    stone520
        7
    stone520  
       2020-04-30 09:41:57 +08:00
    命名也太长了
    baxtergu
        8
    baxtergu  
       2020-04-30 11:20:47 +08:00
    reducer 拆分下 然后用 combineReducer 的方式会清楚一点。如果还不行的话尝试考虑用 middleware 去做更高级的处理
    kimiler
        9
    kimiler  
    OP
       2020-04-30 12:41:29 +08:00
    @KuroNekoFan 是的呀,不然咋控制呢,我没想到好的办法
    kimiler
        10
    kimiler  
    OP
       2020-04-30 12:43:39 +08:00
    @MintZX 好的,我了解了解,谢谢老哥
    kimiler
        11
    kimiler  
    OP
       2020-04-30 12:45:01 +08:00
    @baxtergu 现在已经用了 combine 了,不过上层是根据模板去划分,现在我们一个页面需要连续调用十几个接口,所以看起来又好多 state
    yuanfnadi
        12
    yuanfnadi  
       2020-04-30 15:00:42 +08:00
    typescript-fsa

    dva-model-creator
    yuanfnadi
        13
    yuanfnadi  
       2020-04-30 15:03:30 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3394 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:17 · PVG 08:17 · LAX 16:17 · JFK 19:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.