Search code examples
javascriptreactjsreact-router

React - onSubmit and useNavigate Pattern


I'm trying to submit & redirect in React using useCallback but I'm not using the hook properly. What's the pattern for saving data and then redirecting?

const onSubmit = useCallback((data: FacilityEntity) => {
  saveFacility(data);
  useNavigate().navigate('/facilities', { replace: true })
}, []);

Solution

  • Issue

    The code is breaking React's Rules of Hooks, specifically calling it in a callback/nested function

    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. You can only call Hooks while React is rendering a function component:

    • ✅ Call them at the top level in the body of a function component.
    • ✅ Call them at the top level in the body of a custom Hook.

    It’s not supported to call Hooks (functions starting with use) in any other cases, for example:

    • 🔴 Do not call Hooks inside conditions or loops.
    • 🔴 Do not call Hooks after a conditional return statement.
    • 🔴 Do not call Hooks in event handlers.
    • 🔴 Do not call Hooks in class components.
    • 🔴 Do not call Hooks inside functions passed to useMemo, useReducer, or useEffect.

    Solution

    Call all React hooks at the top level. Move the useNavigate hook call outside the callback function and specify all appropriate hook dependencies.

    Example:

    const navigate = useNavigate();
    
    ...
    
    const onSubmit = useCallback((data: FacilityEntity) => {
      saveFacility(data);
      navigate('/facilities', { replace: true });
    }, [navigate, saveFacility]);