0.9.3 • Published 7 years ago

redux-echos v0.9.3

Weekly downloads
4
License
BSD-2-Clause
Repository
github
Last release
7 years ago

redux-echos

A lightweight redux middleware to decouple and serialise state dependencies.

This sounds awful. Or a better version:

It helps to deal with the to-be-laterly-dispatched actions.

Scenarios

  • state dependency
  • action workflow

Examples

First of First, but not actually

Apply echos as a middleware to the redux store.

import echos from 'redux-echos'
import { createStore, applyMiddleware } from 'redux'

const store = createStore(reducer, applyMiddleware(echos))

note-1: this step may be safely skipped sometimes when redux-thunk is here and you would dispatch all echo actions manually.

note-2: If note-1 does not make clear sense for you, applying the middleware is a safer option.

Action Forking

An action, in its reducer, may spawn other action(s) now.

import { echo } from 'redux-echos'

const reducer = (state, action) => {
  if (action.type === 'The/Source/ACTION') {
    echo({
      type: 'An/Echo/ACTION',
      some: state.an.important.value
    }, action)
    return {...state, key: 'new-value'}
  }
  return state
}

And of course, the function echo() can also be called out of a reducer to queue an action.

Action Chain

Instead of emitting one or several independent actions, you can make a series of actions, which can have thunks, to be dispatched sequentially.

import { chain } from 'redux-echos'

const reducer = (state, action) => {
  if (action.type === 'User/Is/AUTHENTICATED') {
    chain(
      NetworkActions.loadUserProfile(), action
    )(
      NetworkActions.loadFriendProfiles()
    )
    return {...state, key: 'new-value'}
  }
  return state
}

And if all actions in a chain are common object actions, like:

chain(A1)(A2)(A3)...

works exactly like:

echo(A1); echo(A2, A1); echo(A3, A2); ...

But if there is a thunk, e.g: A1, then A2 will only be dispatched after A1's resolved action has been dispatched.

If the resolved action is still a thunk, A2 will continue to wait recursively until a final action is dispatched.

note-1: currently, redux-echos only supports redux-thunk.

note-2: if the source action is not empty, for example:

chain(A1, A0)(A2)(A3)...

can be coded as:

import { follow } from 'redux-echos'
follow(A0)(A1)(A2)(A3) ...

since the A0 is taken as the source action, follow(...) will not try to dispatch it.

note-3: if you need more complex workflow like feature of forking & merging, please refer to redux-action-flow

Action Translating

A state may associate itself with another one which it depends on.

import { listen } from 'redux-echos'

const translator = (action, state) => ({
  type: 'An/Echo/ACTION',
  some: state.an.important.value
})

listen('The/Source/ACTION', translator)

or apply a selector to help the translator

const translator = (action, value) => ({
  type: 'An/Echo/ACTION',
  some: value
})

const selector = state => state.an.important.value

listen('The/Source/ACTION', translator, selector)

Coding Practice

  • w/ or w/o redux-thunk
  • reducer-centred code organising.
  • analyse action flow.

API Reference

Basics

They should be enough for common scenarios.

default exports: middleware(store) => (next) => (action)

the middleware

echo(action, source)

generate an echo action for an target action.

chain(action, source)

create an action chain from an action with an optional source action.

follow(source)

create an action chain from an source action.

listen(actionType, translator, selector)

listen to a type of action to apply a translator to generate none, one or more forked actions.

Advanced

They should be used with a little bit carefulness.

thunk(action, source) => (dispatch)

explicitly create a thunk as the echo action for an optional source action.

squeak(action, source)

explicitly create an common object echo action for an optional source action.

create(action, source)

automatically create a thunk or an object by the existence of redux-thunk.

echos()

peek all current queued echo actions.

thunkEnabled()

query if the thunk mode is enabled.

enableThunk()

explicitly to enable thunk mode.

disableThunk()

explicitly to disable thunk mode.

translators(actionType)

peek all listening translators (as an object of action-type -> array-of-translator map) or an array of translators for the actionType.

unlisten(translator, actionType)

remove a translator from all actions or a particular action.

Tour of Implementation

  • Why not Observable?
  • Design Principles
  • Performance Concerns

The Last Of Last, actually

In this document, the word state is actually used with the meaning of sub-state since it is not referring the root state of the redux store.

0.9.3

7 years ago

0.9.2

7 years ago

0.9.1

7 years ago

0.8.6

7 years ago

0.8.5

7 years ago

0.8.1

7 years ago

0.6.2

7 years ago

0.6.1

7 years ago

0.4.3

7 years ago

0.4.2

7 years ago

0.4.1

7 years ago

0.3.2

7 years ago

0.2.2

7 years ago

0.2.1

7 years ago