如何 简化的 Reducer 类的 actionType 对象方法上重复对象

来源:6-2 类的装饰器(2)

活捉一个刘小贱

2021-01-31

react reducer 项目的如何的简化的代码

import {
    ADD_TODO_ITEM,
    CHANG_INPUT_VALUE,
    DELETE_TODO_ITEM
} from './actionType'

class Reducer {
    actionType = {
        [CHANG_INPUT_VALUE]: (state, value) => {
            const newState = JSON.parse(JSON.stringify(state))
            newState.inputValue = value
            return newState
        },
        [ADD_TODO_ITEM]: state => {
            const newState = JSON.parse(JSON.stringify(state))
            if(!newState.inputValue.length) {
                message.warn('请输入内容')
                return
            }
            newState.todoList.push(state.inputValue)
            newState.inputValue = ''
            return newState
        },
        [DELETE_TODO_ITEM]: (state, value) => {
            const newState = JSON.parse(JSON.stringify(state))
            newState.todoList.splice(value, 1)
            return newState
        }
    }


    getReducer(state, action) {
        try {
            const { type, value } = action
            return this.actionType[type](state, value)
        } catch (error) {
            console.warn(error.message)
            return state
        }
    }
}

const defaultState = {
    todoList: [],
    inputValue: ''
}

export default (state = defaultState, action) => {
    return new Reducer().getReducer(state, action)
}

以上代码 Reducer 类中 actionType 对象的上的每一个方法都重复了以下的代码

const newState = JSON.parse(JSON.stringify(state))
return newState

这两行代码的就是在每个方法中 都会存在 如何进行简化

注意: 这里我是用了装饰器的模式 但是改造不成功

以下是使用装饰器模式进行改造但是没有的改造成功

function nameDecorator(target, key, descriptor) {
    const temp = descriptor.initializer()
    const fnObject = {}
    Object.keys(temp).forEach((fn, index) => {
        try {
            const fnString = temp[fn].toString()
            const fnStringReplace = fnString.replace('state', 'oldState')
            const fnStringSplit = fnStringReplace.split('\n')
            fnStringSplit[0] = fnStringSplit[0] + `const newState = JSON.parse(JSON.stringify(oldState));`
            fnStringSplit[fnStringSplit.length - 2] = fnStringSplit[fnStringSplit.length - 2] + `return newState`
            const fnStringJoin = fnStringSplit.join('')
            const tempFnString = fnStringJoin.replaceAll('      ', '')
            const fnStringNewState = tempFnString.replaceAll('state', 'newState')
            const addFnName = fnStringNewState.replace('function', 'function ' + fn)
            fnObject[fn] = new Function('return ' + addFnName)
        } catch (error) {
            console.error(error)
        }
    })

    console.log(fnObject)
}

@nameDecorator
class Reducer {
    actionType = {
        [CHANG_INPUT_VALUE]: (state, value) => {
            const newState = JSON.parse(JSON.stringify(state))
            newState.inputValue = value
            return newState
        },
        [ADD_TODO_ITEM]: state => {
            const newState = JSON.parse(JSON.stringify(state))
            if(!newState.inputValue.length) {
                message.warn('请输入内容')
                return
            }
            newState.todoList.push(state.inputValue)
            newState.inputValue = ''
            return newState
        },
        [DELETE_TODO_ITEM]: (state, value) => {
            const newState = JSON.parse(JSON.stringify(state))
            newState.todoList.splice(value, 1)
            return newState
        }
    }
}
写回答

3回答

DamonsWays

2021-09-28

直接用rtk不香吗

0
0

活捉一个刘小贱

提问者

2021-02-08

export function handleRepeatCodeFn(state, callback) {    
    const newState = JSON.parse(JSON.stringify(state))    
    callback && callback(newState)    
    return newState    
}

在 reducer 代码中就可以直接写业务逻辑而不用管从重复的代码

//img.mukewang.com/szimg/6021059b094b29c409421168.jpg



0
0

活捉一个刘小贱

提问者

2021-01-31

这里可以通过高价函数的进行优化嘛

0
2
活捉一个刘小贱
回复
Dell
虽然这里的业务逻辑的确不是很复杂 但是这里充斥着大量的 if else 和 switch case 并且有很多的重复性的代码 如 const newState = JSON.parse(JSON.stringify(state)) 。。。return newState 。。。 这里我之前有想到使用设计模式的装饰器模式 但是太过于复杂 后来我通过封装一个高阶函数 从而简化代码的编写
2021-02-08
共2条回复

专为小白设计的TypeScript入门课

Dell老师专为TypeScript小白打造的,全栈式教学TS入门课程

2249 学习 · 506 问题

查看课程