https://res.cloudinary.com/practicaldev/image/fetch/s--s1Umsv5L--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5jyso6f8y1oat967vyq.jpg

How to wait for 2 actions to dispatch another? - Redux Saga

6

0

redux

sagas

react

javascript

Published at Mar 12 2021 Updated on Mar 13 2021

In some situations, you may want to dispatch an action only after 2 actions have been dispatched in redux-saga, next I will explain step by step how to get this.

First, I will explain the scenario:

  1. Imagine that we have a component called Counter, and it has a button to multiply a value.
  2. A value should be multiplied only when action A followed by action B has been dispatched in order.
  3. If the aforementioned in the previous point is not fulfilled, the action C (multiply action) is not dispatched.

The Counter component has the next signature.

//Counter.js
const Counter = ({ value, initialAction, multiply }) => (
  <div>
    Current Value: {value} times{" "}
    <button onClick={initialAction}>Action A</button>{" "}
    <button onClick={multiply}>Action B</button>
  </div>
);

Enter fullscreen mode Exit fullscreen mode

Counter, has 2 buttons, the first one will be used to dispatch an initial action to process into a saga, then it will dispatch the FIRST ACTION, as shown in the following code.

//sagas.js
import { put, takeLatest, take } from "redux-saga/effects";

export function* initialSaga() {
  // side-effects (http calls)...
  yield put({ type: "FIRST_ACTION" });
}

export function* multiply() {
  // do other things...
  yield take(["SECOND_ACTION"]);
  yield put({ type: "MULTIPLY" });
}

export default function* rootSaga() {
  yield takeLatest("INITIAL_ACTION", initialSaga);
  yield takeLatest("FIRST_ACTION", multiply);
}
Enter fullscreen mode Exit fullscreen mode

The magic occurs in multiply generator function, because it will wait until SECOND_ACTION is dispatched to continue and dispatch a MULTIPLY action.

 yield take(["SECOND_ACTION"]);
 yield put({ type: "MULTIPLY" });
Enter fullscreen mode Exit fullscreen mode

So, when second button (multiply) is clicked, SECOND_ACTION action will be dispatched and multiply generator will continue from the line where it ended previously.

Graphically follow the following order.

Alt Text

By the way, the multiplication is done inside a reducer.

//reducer.js
export default function counter(state = 1, action) {
  switch (action.type) {
    case "MULTIPLY":
      return state * 2;
    default:
      return state;
  }
}
Enter fullscreen mode Exit fullscreen mode

In summary, a value will be multiplied only when 2 actions have been previously executed.

Below you have a complete example.

Redux-Saga is fun and very easy to use, and I love it for that.

Thank you for reading my blog post.
Fabian

@foqc - copyright 2017 - 2021