Search code examples
javascriptreactjsnext.jsmaterial-uiredux-toolkit

Getting error when trying to use Redux Toolkit with MUI ToggleButtonGroup component


The error message begins as:

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component.

The handleChange function ran without error until I tried to update Redux state with a dispatcher.

This worked fine:

const [alignment, setAlignment] = React.useState('12');

const handleChange = (event, newAlignment) => {
  setAlignment(newAlignment);
};

But I want to elevate the state to Redux-Toolkit. Changing the function as below caused the error:

const dispatch = useDispatch;

const handleChange = (event, newAlignment) => {
  dispatch(setNbTasks(newAlignment));
};

I tried a couple of things, but got nowhere, the details are above.


Solution

  • You are saving the useDispatch hook to variable named dispatch and then calling the hook function from the callback function which breaks the Rules of Hooks.

    Only Call Hooks at the Top Level

    Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls.

    const dispatch = useDispatch; // dispatch === useDispatch -> true
    
    const handleChange = (event, newAlignment) => {
      dispatch(setNbTasks(newAlignment)); // -> useDispatch(....); 😞
    };
    

    The useDispatch hook should be invoked first, and the returned dispatch function saved to local variable dispatch.

    const dispatch = useDispatch(); // Invoke hook, get dispatch function
    
    const handleChange = (event, newAlignment) => {
      dispatch(setNbTasks(newAlignment)); // Ok dispatch call now 😀
    };