При срабатывании 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');
  }
}
→ Ссылка