Home > database >  useNavigate() in react router v6 to redirect to path if user is logged in
useNavigate() in react router v6 to redirect to path if user is logged in

Time:08-06

In older react versions i was able to use this code to redirect if user is logged in:

history.push('/login?redirect=shipping')

Now in v6 i am using the useNavigate functions instead of history.push but i dont know how to check if user is logged in with navigate, please let me know if you need more of my code to answer, currently this is my navigate code:

let navigateCart = useNavigate() 

// some code here

navigateCart('/login?redirect=shipping') // the mistake is inside the parenthesis here but i dont know what it is!

This is not working it is taking me to .../login/shipping instead of .../shipping

This is my router config:

<BrowserRouter>
        <Container><Routes>
            <Route path='/' element={< HomeScreen />} exact />
            <Route path='/login' element={< LoginScreen />} />
            <Route path='/profile' element={< ProfileScreen />} />
            <Route path='/shipping' element={< ShippingScreen />} />
        </Routes></Container>
</BrowserRouter>

Login Screen Function :

function LoginScreen() {

    let navigateLog = useNavigate()
    let location = useLocation()

    const [email, setEmail] = useState('')
    const [password, setPassword] = useState('')

    const dispatch = useDispatch()

    const redirect = location.search ? location.search.split('=')[1] : '/'
    

    const userLogin = useSelector(state => state.userLogin)
    const { error, loading, userInfo } = userLogin


    useEffect(() => {
        if (userInfo) {
            navigateLog(redirect)
        }
    }, [navigateLog, userInfo, redirect])

    const submitHandler = (e) => {
        e.preventDefault()
        dispatch(login(email, password))
    }

CodePudding user response:

Issue

The redirect target path is "shipping" instead of "/shipping". In react-router-dom@6 there are relative paths and absolute paths. The difference is simple, absolute paths start with a leading "/" character while relative paths do not. navigate("shipping") will append "shipping" to the end of the current pathname and navigate there.

Solution

Either prepend the leading "/" when navigating:

navigate(`/${navigateLog}`, { replace: true });

Or include it when you initially navigate:

navigateCart('/login?redirect=/shipping');

You'll likely also want to use the useSearchParams hook to access the redirect query parameter instead of relying on it to be at a specific string position.

function LoginScreen() {
  const navigateLog = useNavigate();
  const [searchParams] = useSearchParams();

  ...

  const redirect = searchParams.get("redirect") || '/';
    
  ...

  useEffect(() => {
    if (userInfo) {
      navigateLog(redirect, { redirect: true });
    }
  }, [navigateLog, userInfo, redirect])

  ...

Note that in issuing the imperative redirect that I've included an options object to the navigate function that specifies replace: true, this is to issue a REPLACE action instead of a PUSH action.

CodePudding user response:

Change this line navigateLog(redirect) inside that useEffect in LoginScreen to this one:

navigateLog(`/${redirect}`);

In your case it's redirecting to /login/shipping instead of /shipping, cause it's like you are calling navigateLog("shipping") since redirect is equal to "shipping", so it's used as a relative path. Which means it takes into account your current url, which is in your case /login.

Here is a working CodeSandbox of a simplified version of your code as well.

  • Related