Home > database >  How to redirect page inside route in react js?
How to redirect page inside route in react js?

Time:12-16

I want to redirect my page URL conditionally. I was using but it did not redirect my page automatically . After refresh the page it works. But I want after changes it redirect automatically.

My Previous Code was:

<Route path='/login' element={ !token ? <Login/> : <Navigate replace to="/dashboard" /> } />

CodePudding user response:

You can't do that. You have to make a context and routing file for that

here is the example of auth routing

import axios from "axios";
import { useState, createContext, useContext, useEffect } from "react";

const AuthContext = createContext();

const AuthProvider = ({ children }) => {
  const [auth, setAuth] = useState({
    user: null,
    token: "",
  });

  // NOTE axios config
  axios.defaults.baseURL = process.env.REACT_APP_API;
  axios.defaults.headers.common["Authorization"] = auth?.token;

  useEffect(() => {
    const data = localStorage.getItem("auth");

    if (data) {
      const parsed = JSON.parse(data);

      setAuth({
        user: parsed.user,
        token: parsed.token,
      });
    }
  }, []);

  return (
    <AuthContext.Provider value={[auth, setAuth]}>
      {children}
    </AuthContext.Provider>
  );
};

const useAuth = () => useContext(AuthContext);

export { AuthProvider, useAuth };

and put the context in index.js

src/index.js

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

import { AuthProvider } from "./context/auth";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <AuthProvider>
    <App />
  </AuthProvider>
);
reportWebVitals();

now, you have to make the routing src/components/route/privateRoute.js

import axios from "axios";
import { Outlet } from "react-router-dom";
import { useEffect, useState } from "react";

import { useAuth } from "../../context/auth";

import Loading from "./Loading";

export default function PrivateRoute() {
  // NOTE context
  const [auth] = useAuth();
  // NOTE ok
  const [ok, setOk] = useState(false);

  useEffect(() => {
    const authCheck = async () => {
      const { data } = await axios.get("auth-check");

      if (data.ok) {
        setOk(true);
      } else {
        setOk(false);
      }
    };

    if (auth?.token) authCheck();
  }, [auth?.token]);

  return ok ? <Outlet /> : <Loading />;
}

Oh I use Loading for the navigation, here it is src/components/routes/loading.js

import { useEffect, useState } from "react";
import { useNavigate, useLocation } from "react-router-dom";

import loadingGIF from "../../images/loading.gif";

export default function Loading({ path = "/login" }) {
  // NOTE state
  const [count, setCount] = useState(3);
  // NOTE variable
  const location = useLocation();
  const navigate = useNavigate();

  useEffect(() => {
    const interval = setInterval(() => {
      setCount((currentCount) => --currentCount);
    }, 1000);

    count === 0 &&
      navigate(path, {
        state: location.pathname,
      });

    return () => clearInterval(interval);
  }, [count, location, navigate, path]);

  return (
    <div className="d-flex justify-content-center align-items-center vh-90">
      <img src={loadingGIF} alt="loading" width="400" height="500" />
    </div>
  );
}

The last but not least, put the routes you want to give the rule with inside it

App.js

<Route path="/dashboard" element={<PrivateRoute />}>
   <Route path="user" element={<UserDashboard />} />
   <Route path="user/orders" element={<UserOrders />} />
   <Route path="user/profile" element={<UserProfile />} />
</Route>

Good luck

CodePudding user response:

You can handle the redirect inside components, or wrap them with a component that does it

Inside login

   let navigate = useNavigate();

   useEffect(() => {

        if (isAuthenticated) {

            let to = `/dashboard`; // some default auth route 
            navigate(from, { replace: true });
        }

    }, [isAuthenticated])

Inside authencitated components

import { Navigate, useNavigate } from 'react-router-dom';

let location = useLocation();

if (!isAuthenticated) {
    console.log('unauthenticated redirect back to login')
    return (<Navigate to="/login" state={{ from: location }} replace />);
}

Keep the routes standard

<Route path='/login' element={<Login/>} />

If you want a better way, then I suggest reading a blog by kent C. Dodds on Authentication in React

Hope it helps

  • Related