React

【Redux Saga】コールバック内で[ yield put ]できない時は[ eventChannel ]を使う

React
この記事は約2分で読めます。

はじめに

Redux Saga内で、actiondispatchしたい時は、yield putを使用します。

ただし、コールバック関数内ではyield putを使用することができません。
yieldはジェネレータ関数内でのみ機能するからです。

そんな時に役に立つ、eventChannelチャンネルについて紹介します。

実装の例

エラーになってしまう書き方

やりたいこと: 何らかのidを購読し、変更があった場合にactionを発行する

ダメな例


function* subscribeId(action) {

    const { id } = action.payload;
    const subscription = subscribe(id).subscribe({
      next: ({ value }) => {
        // これはエラー!
        yield put(action)
      },
    });
    return subscription.unsubscribe;
}

うまくいく書き方

  • コールバック内でチャンネルに向けてアクションを送信します
  • コールバック外でアクションを待ち受け、受け取ります
function* subscribeId(action) {
  // チャンネルを用意する
  const channel = eventChannel((emitter) => {

    const { id } = action.payload;
    const subscription = subscribe(id).subscribe({
      next: ({ value }) => {
        // チャンネルに向けて送信!
        emitter(roomID);
      },
    });
    return subscription.unsubscribe;
  });

  // -----------
  //  コールバックの外でアクションを待ち受ける
  // -----------
  while (true) {
    const action = yield take(channel);
    yield put(action);
  }
}

まとめ

チャンネルを用意することで、まるでコールバックから値を外に送信するような実装が可能になりました。📡