Listeners

Please help write this section or read more about kea-listeners on github!

Installation

First install the kea-listeners package:

# if you're using yarn
yarn add kea-listeners

# if you're using npm
npm install --save kea-listeners

Then install the plugin:

import listenersPlugin from 'kea-listeners'
import { resetContext } from 'kea'

resetContext({
  createStore: true,
  plugins: [ listenersPlugin ]
})

Sample usage

kea({
  // ...

  listeners: ({ actions, values, store, sharedListeners }) => ({
    // action that conditionally calls another action
    [actions.openUrl]: ({ url }) => {
      // get the value from the reducer 'url'
      const currentUrl = values.url

      if (url !== currentUrl) {
        actions.reallyOpenTheUrl(url)
      }
    },

    // listen to any redux action type, not just ones defined in this logic
    'LOCATION_CHANGE': (payload) => {
      // do something with the regular redux action
      console.log(payload)
      store.dispatch({
        type: 'REDUX_ACTION',
        payload: { redux: 'cool' }
      })
    },

    // two listeners with one shared action
    [actions.anotherAction]: sharedListeners.sharedActionListener,
    [actions.yetAnotherAction]: sharedListeners.sharedActionListener,

    // Debounce for 300ms before making an API call
    // Break if this action was called again while we were sleeping
    [actions.debouncedFetchResults]: async ({ username }, breapoint) => {
      // If the same action gets called again while this waits, we will throw an exception
      // and catch it immediately, effectively cancelling the operation.
      await breakpoint(300)

      // Make an API call
      const user = await API.fetchUser(username)

      // if during the previous fetch this action was called again, then break here
      breakpoint()

      // save the result
      actions.userReceived(user)
    },

    // you can also pass an array of functions
    [actions.oneActionMultipleListeners]: [
      (payload, breakpoint, action) => { /* ... */ },
      sharedListeners.doSomething,
      sharedListeners.logAction
    ]
  }),

  // if multiple actions must trigger similar code, use sharedListeners
  sharedListeners: ({ actions, values, store }) => ({
    // all listeners and sharedListeners also get a third parameter:
    // - action = the full dispatched action
    sharedActionListener: function (payload, breakpoint, action) {
      if (action.type === actions.anotherAction.toString()) {
        // handle this case separately
      }
      // do something common for both
      console.log(action)
    }
  })
})