redux减少了动作和减速器的样板

时间:2017-12-27 16:47:21

标签: javascript redux

我试图弄清楚这种情况的最佳做法。

2上下文:SPORT todos& HOME todos。

所以2个动作文件:

export const SPORT_ADD_TODO = `[SPORT] ADD TODO`
export const HOME_ADD_TODO = `[HOME] ADD TODO`

和2个reducer文件

homeReducer(state, action) {
  switch(action.type) {
     case HOME_ADD_TODO:
        return Object.assing({}, state, {
           todos: action.payload
        })
     default:
        return state;
  }
}

sportReducer(state, action) {
      ....
}

有这种情况的官方解决方案吗? 我不想重复我的自我。 减速机具有相同的功能

3 个答案:

答案 0 :(得分:1)

在软件开发中,当我们想要创建类似对象的多个实例时,我们使用工厂来创建对象。这里Redux上下文中的reducer只是一个纯函数,它是一个对象类型是Javascript。所以工厂规则也适用于此。

创建createTodoReducer工厂:

function createTodoReducer(initialState, {addType}) {
  return function(state = initialState, action) {
    switch(action.type) {
      case addType:
        return {...state, todos: action.payload}
    }
  }
}

现在使用工厂实例化sportTodosReducerhomeReducer

const homeReducer = createTodosReducer({todos: []}, {addType: 'HOME_ADD_TODO'});
const sportsReducer = createTodoReducer({todos: []}, {addType: 'SPORTS_ADD_TODO'})

您可以添加任何类型来修改reducer状态,例如addType,并使用工厂共享相同的逻辑。

答案 1 :(得分:1)

您需要再次考虑您的应用架构。通常,可重复使用的减速器/动作是不正确的。

为什么不正确?在目前的观点中,编写可重复使用的减速器和动作,更少的样板,而不是“干”似乎很棒。在你的应用程序的示例中。家庭和运动的'ADD_TO_DO'是平等的。

但是将来这将是危险的,认为你的老板/消费者需要未来的体育add_to_do。如果您更改可重复使用的减速器中的逻辑。你的应用程序将破产。 (您可以使用if语句开始修补可重复使用的reducer以使其正常工作,但如果您的应用程序增长,则不灵活/可读/维护)。

所以是的,似乎你需要在这种情况下写2个减速器和2个动作文件。在目前它填补相同,但在未来它将是有利和灵活的。

答案 2 :(得分:0)

刚刚找到Autodux

在一个对象中定义的动作,减速器,初始状态和选择器。 如果仅给出初始状态,它将自动在状态形状上生成其余状态。

太棒了!

// From this
const actionTypes = {
  INCREMENT: 'INCREMENT',
  DECREMENT: 'DECREMENT'
}

const actions = {
  increment: () => ({type: actionTypes.INCREMENT}),
  decrement: () => ({type: actionTypes.DECREMENT})
}

const counter = (state = 0, action) => {
  switch (action.type) {
    case actionTypes.INCREMENT:
      return state + 1
    case actionTypes.DECREMENT:
      return state - 1
    default:
      return state
  }
}

// To this
const counter = autodux({
  slice: 'counter',
  initial: 0,
  actions: {
    increment: state => state + 1,
    decrement: state => state - 1
  }
});