JSPM

@0y0/use-reducer-x

1.0.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 5
  • Score
    100M100P100Q31890F
  • License MIT

An alternative to React.useReducer that accepts middlewares to do some cool things before and after dispatch.

Package Exports

  • @0y0/use-reducer-x

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@0y0/use-reducer-x) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@0y0/use-reducer-x · GitHub license npm Status

@0y0/use-reducer-x is an alternative to React.useReducer that accepts middlewares to do some cool things before and after dispatch.

Inspired by Redux Middleware.

3-second quick look

import useReducerX from '@0y0/use-reducer-x'

function App() {
  const middlewares = [
    ({ getState, dispatch }) => next => action => {
      // do something before dispatch...
      next(action)
       // do something after dispatch...
    }
  ]
  const [state, dispatch] = useReducerX(reducer, initialState, middlewares)
  // ...
}

Installation

npm install @0y0/use-reducer-x --save

Real-world Usage

import React from 'react'
import useReducerX from '@0y0/use-reducer-x'
import thunkMiddleware from 'redux-thunk'

function logMiddleware({ getState }) {
  return next => action => {
    console.log('Prev State:', getState())
    console.log('Action:', action)
    next(action)
    console.log('Next State:', getState())
  }
}

function gaMiddleware({ getState }) {
  return next => action => {
    window.ga && window.ga('send', 'event', 'Action', action.type)
    next(action)
  }
}

function useAppReducer(reducer, inititalState) {
  return useReducerX(reducer, inititalState, [
    thunkMiddleware,
    logMiddleware,
    gaMiddleware
  ])
}

function counterReducer(state, action) {
  switch (action.type) {
    case '+1': return { count: state.count + 1 }
    case '-1': return { count: state.count - 1 }
    case '0': return { count: 0 }
    default: return state
  }
}

function resetCounterAfter1Second() {
  return dispatch => setTimeout(() => { dispatch({ type: '0' }) }, 1000)
}

function App() {
  const [state, dispatch] = useAppReducer(counterReducer, 0)
  return (
    <React.Fragment>
      <button onClick={() => dispatch({ type: '+1' })}>+</button>
      <button onClick={() => dispatch(resetCounterAfter1Second())}>Reset</button>
      <button onClick={() => dispatch({ type: '-1' })}>-</button>
      <br />
      Count: {state.count}
    </React.Fragment>
  )
}

Try the demo in codesanbox.

License

MIT