5

I have two sections of my app. They each have their own saga middleware, but both are never instantiated at the same time. It's always one or the other. For example, a saga to handle login and another to handle the main page.

I'm wondering how should I should be tearing down the redux saga when navigating between the two sections of my app. Am I supposed to let it just be garbage collected? But what if there are still actions that are in queue? Those actions would still need to be flushed from the buffers.

epikhighs
  • 458
  • 3
  • 14

3 Answers3

2

You can cancel you watcher on location change. So the code for your watcher would be something like this:

import { takeLatest, take, cancel } from 'redux-saga/effects';
import { LOCATION_CHANGE } from 'react-router-redux';

function* watchTheRequest() {
    const watcher = yield takeLatest('SOME_TYPE', callMySaga);
    yield take(LOCATION_CHANGE);
    yield cancel(watcher);
}

So when you move from one part to another, the watchers will be cancelled. You can re-inject watchers when you move to that route.

Vivek V Dwivedi
  • 2,510
  • 2
  • 28
  • 39
2

You can cancel the task returned from the middleware run function which will stop all child sagas.

Here is a code excerpt with an example of cancelling the task when a component unmounts:

const sagaMiddleware = createSagaMiddleware();
const store = createStore(
  reducer,
  compose(applyMiddleware(sagaMiddleware)),
);
const sagaTask = sagaMiddleware.run(saga);

const App = () => {
  useEffect(() => {
    return function componentWillUnmount() {
      sagaTask.cancel();
    };
  });

  return (
    <Provider store={store}>
      <div>Hello World</div>
    </Provider>
  );
};

There is also a related question with more information in the question comments.

jeff
  • 70
  • 1
  • 6
0

I tried various work arounds for the same but failed Finally //make a temporary actions and its corresponding reducer //my reducer default value was false and on committing its action(never) it will be true

in watchSaga - i.e. your export default function of your saga file, this is the function you import in index.js of saga and call it in rootSaga

export function* setTopHeadlinesSAGA() {
    const loadBool = yield select(getloadBool);
    while (!loadBool) {
        yield take(SET_TOP_HEADLINES)
        yield call(handleTopHeadlines)
    }
}

Her instead of takeEvery/takeLatest use take and call, because unlike takeEvery and takeLatest, take need a loop( while(true) ) to continuesly work on the action without explicit calling

refer : https://redux-saga.js.org/docs/advanced/FutureActions.html

Hence you will get only one output at a time

Shubham Kakkar
  • 581
  • 6
  • 4