egasimus / redux-helper

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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


Languages

Language:JavaScript 100.0%