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
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.