You can have redux-saga
listen in on event sources other than the Redux Store. The default nature of redux-saga
is pull based. We need to write a saga that is push based, so that the external event listener like an API can push updates to the saga.
You can achieve this by using the eventChannel
factory function from redux-saga
.
You can start off by writing your listener function that uses the eventChannel
factory function within it. Here is an example of how your listener can look:
import { eventChannel, END } from 'redux-saga';
function externalSourceChannel() {
return eventChannel((emit) => {
externalSource().on('change', (data) => {
// Example: If some condition is met, close the channel (returns the unsubscribe function)
if (data.someValue === 'someOtherValue') {
emit(END);
}
emit(data);
});
// This subscriber function must return an unsubscribe function
return () => {
externalSource().off();
};
});
}
An example of how the saga would then maybe look would be something like this:
function* externalSourceListener() {
const chan = yield call(externalSourceChannel);
try {
while (true) {
const pushedData = yield take(chan);
yield put(someActionHandler.success(pushedData));
}
} catch (error) {
yield put(someActionHandler.failure(error));
}
}
function* takeLatestExternalSourceListener() {
const watcher = yield takeLatest(START_EXTERNAL_EVENT_LISTENER, externalSourceListener);
// Suspend execution until location changes
yield take(LOCATION_CHANGE);
yield cancel(watcher);
}
You can find the eventChannel
factory function documentation by clicking here.