How to start a redux saga watcher using runSaga
Asked Answered
B

2

3

I am not able to figure out from the documentation how to start a redux saga watcher using runSaga. Suppose I have the following in saga.js:

export function* fetchJokeSaga(action) {
  try {
    const response = yield call(axios.get, "...");
    yield put({ type: "UPDATE_JOKE", payload: response });
  } catch (e) {}
}

export default function* watcherSaga(action) {
  yield takeEvery("FETCH_JOKE", fetchJokeSaga);
}

and the following in Component.js:

const Component = () => {
  const store = useStore();
  const dispatch = useDispatch();
  const { joke } = useSelector(state => state);

  React.useEffect(() => {
    runSaga({ dispatch, getState: store.getState }, watcherSaga);
  }, []);

  return joke;
};

I'm not able to trigger the api call using dispatch({ type: 'FETCH_JOKE' }).
But when I use fetchJokeSaga directly as runSaga({ dispatch, getState: store.getState }, fetchJokeSaga);, it makes the api call immediately.
How do I dynamically start watcherSaga so that I can dispatch 'FETCH_JOKES' later?

Brackish answered 9/9, 2019 at 17:26 Comment(1)
github.com/redux-saga/redux-saga/issues/1724Batish
B
1

azundo almost had the solution. You need to 'put' some actions in the channel to get the generator started.

import {stdChannel, runSaga} from 'redux-saga';

const Component = () => {
   const store = useStore();
   const dispatch = useDispatch();
   const { joke } = useSelector(state => state);

   React.useEffect(() => {
       const channel = stdChannel();
       runSaga({ dispatch, getState: store.getState, channel}, watcherSaga);
       channel.put({ type: 'FETCH_JOKE' });
   }, []);

   return joke;
};

Hope this helps.

Brunn answered 6/3, 2020 at 18:37 Comment(0)
A
0

Since your watcher saga is using the take effect it needs a channel to listen on. Unless you're doing something custom you'll want the normal stdChannel that redux-saga provides:

import {stdChannel, runSaga} from 'redux-saga';

const Component = () => {
  const store = useStore();
  const dispatch = useDispatch();
  const { joke } = useSelector(state => state);

  React.useEffect(() => {
    runSaga({ dispatch, getState: store.getState, channel: stdChannel()}, watcherSaga);
  }, []);

  return joke;
};
Autograph answered 9/9, 2019 at 18:36 Comment(2)
I tried using a channel. But no luck. I see my actions being dispatched but the watcher is not waking up to make the api call.Brackish
As mentioned here https://mcmap.net/q/1626723/-how-to-start-a-redux-saga-watcher-using-runsaga we need to call put on the channel to trigger the watcher :)Romain

© 2022 - 2024 — McMap. All rights reserved.