Skip to content

Releases: blueish9/redux-dispatcher

v1.9 implement Concurrency to subscribe for action's result

29 Oct 07:26
0821042
Compare
Choose a tag to compare

Retrieve side effect result after dispatching an action (no more callback)

When your action trigger some side effect (like fetching API),
you can use built-in hooks dispatchResult or waitResult to dispatch and subscribe for results from action.

Use case with React:

const mapDispatchToAC = {
  fetchProfile: userId => ({ userId }),
};

const userDispatcher = createDispatcher('user', mapDispatchToAC);
// Component A
async componentDidMount() {
  const action = userDispatcher.fetchProfile(userId)
  const profile = await action.waitResult()
  // profile = { name: "Emily" }
}

In your side effect handler (example with Redux Saga):

import { take } from 'redux-saga/effects'

function* fetchProfile(action) {
  const profile = { name: "Emily" }   // call your side effect here (like API request)
  action.dispatchResult(profile)
}

function* sagaWatcher() {
  yield take(userDispatcher.fetchProfile, fetchProfile)
}

If you want to subscribe for result from other places:

// Component A calls userDispatcher.fetchProfile
// but Component B and Component C also want to subscribe for the action's result

import { waitResult } from "redux-dispatcher";

// Component B
async componentDidMount() {
  // this Promise will be resolved when dispatchResult is called.
  // if dispatchResult has already been called before, this waitResult will immediately return a cached result
  const result = await waitResult(userDispatcher.fetchProfile)
}

// Component C
componentDidMount() {
  const unsubscribe = waitResult(userDispatcher.fetchProfile, result => {
    // each time dispatchResult is called, this callback will be triggered
  })

  // to remove the callback from listening to result, simply call unsubscribe()
}

// in Component A, you can also subscribe for continuous results like in Component C
componentDidMount() {
  userDispatcher.fetchProfile(userId).waitResult(result => {
    // each time dispatchResult is called, this callback will be triggered
  })
}