Skip to content

egasimus/redux-helper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

Redux Brevity

Rationale

The canonical usage pattern for Redux requires you to write each action's name at least 6 times in 3 different places in your codebase - even if your code only calls the action once.

Thanks to JavaScript's built-in metaprogramming capabilities, this tiny library saves you all that repetition. It also uses Immer to produce each new state, saving you even more time by automatically taking care of state immutability.

Overview

  • Remember: In JavaScript, a function is a first-class object. This means a function can have custom properties - including other functions.

  • reduxHelper returns a reducer function which also doubles as a collection of action creators.

// Reducers/Counter.js
const INITIAL_STATE = { value: 0 }
const CounterReducer = reduxHelper('Counter', INITIAL_STATE, {
  INCREMENT (state, arg) {
    state.value += arg
  },
  RESET (state) {
    state.value = 0 
  }
})
  • Action creators are now attached to the reducer. This does not violate the basic premise of Redux: actions are still decoupled from their effects, even though you can now define them in one place.
// Components/MyComponent.js
import CounterReducer from '../Reducers/Counter.js'
const store = createStore(CounterReducer)
const action = CounterReducer.INCREMENT(1) // { type: 'Counter/INCREMENT', arg: 1 }
store.dispatch(action)
store.dispatch(CounterReducer.RESET())

How this would look in plain Redux:

// Constants/Counter.js
export const INCREMENT = 'Counter/INCREMENT'
export const RESET = 'Counter/RESET'
// ActionCreators/Counter.js
import { INCREMENT, RESET } from '../Constants/Counter.js'
export const increment = arg => ({ type: INCREMENT, arg })
export const reset = arg => ({ type: RESET, arg })
// Reducers/MyReducer.js
import { INCREMENT, RESET } from '../Constants/Counter.js'
import produce from 'immer'
export function myReducer (state, action) {
  return produce(state, draft =>{
    switch (action.type) {
      case INCREMENT:
        state.value += 1
        break
      case RESET:
        state.value = 0
        break
    }
  })
}
// Components/MyComponent.js
import { increment, reset } from '../ActionCreators/Counter.js'
const store = createStore(CounterReducer)
const action = increment(1) // { type: 'Counter/INCREMENT', arg: 1 }
store.dispatch(action)
store.dispatch(reset())

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published