Maximum update exceeded (useEffect + Redux Hooks)

Viewed 108

I am using Redux hooks. I am tried to dispatch from useEffect, but get error "Maximum update exceeded"

const state = useSelector((state: RootStateOrAny) => ({data: state}));

const dispatch = useDispatch();

React.useEffect(() => {
    if (state.data.topics.topics === null) dispatch({type: 'GET_TOPICS'});

    console.log(state.data.topics.topics)

}, [dispatch, state]);
1 Answers

On each action dispatched to Redux, state is recreated. I.e. look at example reducer below

const reducer = (state, action) => {
  switch(action.type) {
    case 'ACTION1":
      return { ...state, prop: action.prop }
    //...
  }
}

When dispatch({ type: 'ACTION1', prop: 'something' }) is called new state object is received. And on every call to dispatch new state object is received.

useEffect has state in it dependency array. useEffect compare dependencies using Object.is to detect changes. So when after call to dispatch new state is got, useEffect is firing again and calls dispatch. This creates infinite loop.

To break the loop, you need to make useSelector more specific. Don't select full state, but only props you'll use.

const topics = useSelector((state: RootStateOrAny) => state.topics.topics);

const dispatch = useDispatch();

React.useEffect(() => {
  if (topics === null) dispatch({type: 'GET_TOPICS'});
  console.log(topics)
}, [dispatch, topics]);
Related