はじめに
Redux Saga内で、action
をdispatch
したい時は、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);
}
}
まとめ
チャンネルを用意することで、まるでコールバックから値を外に送信するような実装が可能になりました。📡