Nodeschool Public Materials

    duxkit

    0.1.5 • Public • Published

    duxkit

    An unofficial, simple, toolkit for organising actions and reducers for Redux

    Inspired by the official redux-toolkit.

    Installation

    npm or yarn

    Duxkit is available as a package on NPM for use with a module bundler or in a Node application:

    # NPM 
    npm i duxkit
     
    # Yarn 
    yarn add duxkit

    Copy 'n Paste

    A goal of duxkit is to be simple enough to be able to just copy and paste the source code here into your own source. createAction, createReducer, and miniStore have no dependencies on other parts of the code, so they can be dropped into your source without a worry. createAsyncAction[1] and createSlice[2] rely on createAction[1,2] and createReducer[2] so if you want to use those you'll have to copy their dependencies too.

    Usage

    createAction()

    createAction(type, customAction?)

    import { createAction } from 'duxkit'
     
    const actionCreator = createAction('myAction')
     
    actionCreator('myPayload')
    // { type: 'myAction', payload: 'myPayload' }
     
    const customActionCreator = createAction('myCustom', (str = '') =>
      str.split('').reverse().join('')
    )
     
    actionCreator('abc')
    // { type: 'myCustom', payload: 'cba' }

    createAsyncAction()

    createAsyncAction(type, asyncAction)

    import { createAsyncAction } from 'duxkit'
     
    const actionCreator = createAsyncAction('fetchUser', async (id) => {
      if (id === 0) {
        throw new Error('demo error')
      }
      await getUserById(id) // { id: 123, name: 'Joe' }
    })
     
    dispatch(actionCreator(123))
    // { type: 'fetchUser/pending' }
    // { type: 'fetchUser/fulfilled', payload: { id: 123, name: 'Joe' } }
     
    dispatch(actionCreator(0))
    // { type: 'fetchUser/pending' }
    // { type: 'fetchUser/rejected', payload: Error{ message: 'demo error' } }

    createAsyncAction() returns a thunk, not an action. Use with store.dispatch().

    createReducer()

    createReducer(initialState, actionHandlers)

    import { createReducer, createAction } from 'duxkit'
     
    const decr = createAction('decr')
     
    const initialState = 0
     
    const actionHandlers = {
      incr: (state) => state + 1,
      [decr]: (state) => state - 1,
    }
     
    const reducer = createReducer(initialState, actionHandlers)
     
    reducer(undefined, { type: 'incr' })
    // 1
     
    reducer(5, decr())
    // 4

    createSlice()

    createSlice({ name, initialState, reducers?, extraReducers? })

    import { createSlice, createAsyncAction } from 'duxkit'
     
    const setAsync = createAsyncAction('counter/setAsync', async (value = 0) => {
      return Promise.resolve(value)
    })
     
    const counter = createSlice({
      name: 'counter',
      initialState: 0,
      reducers: {
        incr: (state) => state + 1,
        decr: (state) => state - 1,
      },
      extraReducers: {
        [`${setAsync}/pending`]: (state) => 0,
        [`${setAsync}/rejected`]: (state) => -1,
        [`${setAsync}/fulfilled`]: (state, action) => action.payload,
      },
    })
    // { name: counter, actions: { incr(), decr() }, reducer() }
     
    counter.actions.incr()
    // { type: 'counter/incr' }
     
    counter.actions.decr()
    // { type: 'counter/decr' }
     
    counter.reducer(undefined, counter.actions.incr())
    // 1
     
    counter.reducer(1, { type: 'counter/setAsync/fulfilled', payload: 42 })
    // 42

    miniStore()

    miniStore(reducer)

    import { miniStore, createSlice } from 'duxkit'
     
    const counter = createSlice({
      name: 'counter',
      initialState: 0,
      reducers: {
        incr: (state) => state + 1,
        decr: (state) => state - 1,
      },
    })
    // { name: counter, actions: { incr(), decr() }, reducer() }
     
    const store = miniStore(counter.reducer)
     
    store.getState()
    // 0
     
    const unsub = store.subscribe((state) => {
      console.log(state)
    })
     
    store.dispatch(counter.actions.incr())
    // console.log: 1
     
    store.dispatch(counter.actions.decr())
    // console.log: 0
     
    unsub()
     
    store.dispatch(counter.actions.decr())
    // console.log not called

    Differences to Redux Toolkit

    Status Name Description
    removed createAsyncThunk() renamed to createAsyncAction()
    added createAsyncAction() renamed from createAsyncThunk()
    added miniStore() simple redux store with thunk support
    changed createReducer() removed immer
    removed configureStore()
    removed createEntityAdapter()
    removed createSelector not re-exported

    Keywords

    none

    Install

    npm i duxkit

    DownloadsWeekly Downloads

    20

    Version

    0.1.5

    License

    MIT

    Unpacked Size

    36.4 kB

    Total Files

    25

    Last publish

    Collaborators

    • jamesford