0
votes

I'm trying to get my grasp on react and redux-saga, and the issue I've faced is that whenever I try to dispatch any state-changing action in a functional component's useEffect hook, for instance, using useDispatch hook, the app freezes. Now the useSelector works just fine, I can get the state.

I've tried reading redux-saga docs' troubleshooting part on app freezing, where it says you have to yield actions, but I have done so:

import { put } from 'redux-saga/effects';

import * as actions from '../actions/index';

export function* globalLoadingSaga(action) {
  yield put(actions.setGlobalLoading());
}

I've also tried dropping parentheses, i.e. leaving:

export function* globalLoadingSaga(action) {
  yield put(actions.setGlobalLoading);
}

It seems to work then, but I get an error: "Error: Actions must be plain objects. Use custom middleware for async actions." And, well, the actions are plain objects:

export const setGlobalLoading = (loading) => {
  return {
    type: actionTypes.SET_GLOBAL_LOADING,
    loading: loading,
  };
};

So this does not seem right to me.

I've also tried to use "fork" instead of "put", but then it gives me yet another error "Error: fork: argument of type {context, fn} has undefined or null fn", and, again, this just doesn't feel right to me.

I've tried googling it, but couldn't find anything that somewhat resembles this issue, and I am lost at this point.

And the strangest thing is that I know, for sure, that such implementation has worked before, flawlessly. I've got it from a project that I created following an online course some few months ago. Back then everything was fine with it. I did try, out of curiosity, to open that project as well to see if it had the same problem, and, well somehow the app froze too. I had not changed anything, didn't even touch it since then, no dependencies were updated, nothing, but the app hanged still as well.

Here is a codesandbox snippet stripped to bare minimum, which also freezes possibly due to some sort of loop: https://codesandbox.io/s/jovial-kowalevski-dotvp?file=/src/index.js

1

1 Answers

1
votes

You are encountering infinite loop of dispatching SET_GLOBAL_LOADING action type.

// App.js
const onSetGlobalLoading = useCallback(
  (boolean) => {
    dispatch(actions.setGlobalLoading(boolean)); // <-- Dispatches action type of 'SET_GLOBAL_LOADING'
  },
  [dispatch]
);

Since you dispatch an action type of SET_GLOBAL_LOADING from your App.js, then you have a saga that listens to an action type of SET_GLOBAL_LOADING. But then in that saga, you also dispatch a SET_GLOBAL_LOADING, which is why it performs infinite loop.

export function* globalLoadingSaga(action) {
  yield put(actions.setGlobalLoading()); // <-- Dispatches action type of 'SET_GLOBAL_LOADING', which is the reason your app freeze
}

So the answer might be, you might dispatch different action on your saga.

enter image description here