Redux Middleware

Redux Middleware

  • Provides a third-party extension
  • Before an action reaches the reducer
  • Ex: logging, async actions...

Example

Logging

let action = addTodo('Use Redux')

console.log('dispatching', action)
store.dispatch(action)
console.log('next state', store.getState())

Attempt #1

Logging manually

Attempt #2

Wrapping Dispatch

function dispatchAndLog(store, action) {
  console.log('dispatching', action)
  store.dispatch(action)
  console.log('next state', store.getState())
}

Attempt #3

Monkeypatching Dispatch

function patchStoreToAddLogging(store) {
  let next = store.dispatch
  store.dispatch = function dispatchAndLog(action) {
    console.log('dispatching', action)
    let result = next(action)
    console.log('next state', store.getState())
    return result
  }
}

Attempt #4

Hiding Monkeypatching

  • Monkeypatching is a hack.
  • Replace any method you like
  • What kind of API is that?

Attempt #4

Hiding Monkeypatching

function logger(store) {
  let next = store.dispatch

  // Previously:
  // store.dispatch = function dispatchAndLog(action) {

  return function dispatchAndLog(action) {
    console.log('dispatching', action)
    let result = next(action)
    console.log('next state', store.getState())
    return result
  }
}

How about returning a new dispatch function

Attempt #4

Hiding Monkeypatching

function applyMiddlewareByMonkeypatching(store, middlewares) {
  middlewares = middlewares.slice()
  middlewares.reverse()

  // Transform dispatch function with each middleware.
  middlewares.forEach(middleware =>
    store.dispatch = middleware(store)
  )
}

applyMiddlewareByMonkeypatching(store, [ logger, crashReporter ])

Attempt #5

Removing Monkeypatching

function logger(store) {
  let next = store.dispatch

  return function dispatchAndLog(action) {
    console.log('dispatching', action)
    let result = next(action)
    console.log('next state', store.getState())
    return result
  }
}

No need to replace to origin dispatch

Made with Slides.com