Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redux reduce boilerplate for actions and reducer

Tags:

i try to figure out what the best practice for this situation.

2 context : SPORT todos & HOME todos.

so 2 action files:

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

and 2 reducer files

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

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

have an official solution for this situation? i don't want to repeat my self. the reducer have the same functionality

like image 843
Liam Avatar asked Dec 27 '17 16:12

Liam


2 Answers

you need to think again on your app architecture. in general reusable reducer/actions is incorrect.

why it's incorrect? in present view, it seem's awesome to write reusable reducer and actions, less boilerplate, and not "DRY". in example of your app. 'ADD_TO_DO' for home and sport are equal.

but in future it will be dangerous, thinking your boss/costumers need future in sports add_to_do. if you change the logic in the reusable reducer. your app will broke. (you can start patch your reusable reducer with if statements to get it work but if your app grow it will be not flexible/ readable/ maintenance ).

so yes it seems you need to write 2 reducers in this case, and 2 actions files. in present it fill equal but in the future it will be advantage and flexible.

like image 129
Lidor Avitan Avatar answered Sep 21 '22 13:09

Lidor Avitan


In software development in general, when we want to create multiple instances of the similar objects, we use factories for object creation. Here the reducer in Redux context is just a pure function which is an object type is Javascript. So the factory rule applies here too.

Create a createTodoReducer factory:

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

Now use the factory to instantiate sportTodosReducer and homeReducer:

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

You can add any types to modify reducer state such as addType and share the same logic by using the factory.

like image 27
Farzad Yousefzadeh Avatar answered Sep 22 '22 13:09

Farzad Yousefzadeh