React router v6 useNavigate function is not working

If you have recently started using the useNavigate hook from react-router v6, you might run into the following scenario. Say write the code as follows:

import { createContext, useContext } from 'react'
import { useNavigate } from 'react-router-dom'

export const AuthContext = createContext(null)

export const useAuth = () => {
  const navigate = useNavigate()
  const context = useContext(AuthContext)

  if (!context.authData) {
    navigate('/', { replace: true })
  }

  return context
}

But your code would call navigate() function but would not navigate to the said location. Its because of the following condition in place in react-router library.

Full code here: https://raw.githubusercontent.com/.../react-router/index.tsx

let activeRef = React.useRef(false);
  React.useEffect(() => {
    activeRef.current = true;
  });

  let navigate: NavigateFunction = React.useCallback(
    (to: To | number, options: NavigateOptions = {}) => {
      warning(
        activeRef.current,
        `You should call navigate() in a React.useEffect(), not when ` +
          `your component is first rendered.`
      );

      if (!activeRef.current) return;

    ...

This sets the activeRef.current using useEffect. So, you would have to call navigate in useEffect as well. So, your code would become as follows:

import { createContext, useContext, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'

export const AuthContext = createContext(null)

export const useAuth = () => {
  const navigate = useNavigate()
  const context = useContext(AuthContext)

  useEffect(() => {
    if (!context.authData) {
      navigate('/', { replace: true })
    }
  }, [])

  return context
}

Did you find this article valuable?

Support JAGDEEP BISHT by becoming a sponsor. Any amount is appreciated!