При срабатывании action вызвать другой action. Saga
Симуляция моего кода. Я хочу перенести слушатель beforeunload из компонента в saga-и. И хочу что бы по закрытию вкладки число выгружалось в localStorage
import { takeEvery, select } from 'redux-saga/effects';
import {
PUT_NUMBER,
UNLOAD,
} from '../reducers/actions';
const putNumWorker = function* () {
const nums = yield select((state) => state.numbers);
localStorage.setItem('numbers', JSON.stringify(nums));
};
const listener = () => {
window.addEventListener('beforeunload', putNumWorker);
};
function* putNumsWatcher() {
yield takeEvery(PUT_NUMBER, putNumWorker );
yield takeEvery(UNLOAD, listener);
}
export default putNumsWatcher;
Я понял, что window.addEventListener('beforeunload', putNumWorker) не сработает, так Listener не принимает итерируемые объекты. У меня ещё есть идея window.addEventListener('beforeunload', putNumWorker); вместо putNumWorker вызывать Action PUT_NUMBER, но я не знаю как это делать в redux-saga, а мои эксперименты никуда меня не привели. Может кто посоветовать, как выйти из ситуации? Ожидаемый результат, при закрытии вкладки, выгрузить numbers из state в localStorage.
Ответы (1 шт):
Решение оказалось, довольно простым, может ещё кому поможет. Я просто добавил канал, для прослушивания события beforeonload
function* catchUnloadChannel() {
try {
const listenerUnload = yield call(() => (
eventChannel((emitter) => {
const windowListener = window.addEventListener('beforeunload', () => {
emitter('page will unload');
return true;
});
return () => {
windowListener.remove();
emitter(END);
};
})
));
yield take(listenerUnload);
yield call(putNum);
} catch {
console.log('error with listener');
}
}