skip to Main Content

main.jsx

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <Provider store={store}>
      <BrowserRouter>
        <ToastContainer />
        <App />
      </BrowserRouter>
    </Provider>
  </React.StrictMode>
)

app.jsx

const App = () => (
  <CustomerRouters />
);

customerRouters.jsx

const CustomerRouters = () => {
    return (
        <div>
            <div>
                <Navbar />
            </div>
            <Routes>
                <Route path='/cart' element={<Cart />} />
                <Route path='/:levelOne/:levelTwo/:levelThree' element={<ProductPage />} />
                <Route path='/product/:productId' element={<ProductDetails />} />
                <Route path='/checkout' element={<Checkout />} />
                <Route path='/account/order' element={<Order />} />
                <Route path='/account/order/:orderId' element={<OrderDetails />} />
                <Route path='/payment/:orderId' element={<PaymentSuccess />} />
                <Route path='/login' element={<HomePage />} />
                <Route path='/register' element={<HomePage />} />
                <Route path='/' element={<HomePage />} />
            </Routes>
            <div>
                <Footer />
            </div>
        </div>
    )
}

auth redux state

actionType

export const REGISTER_REQUEST = 'REGISTER_REQUEST';
export const REGISTER_SUCCESS = 'REGISTER_SUCCESS';
export const REGISTER_FAILURE = 'REGISTER_FAILURE';

export const LOGIN_REQUEST = 'LOGIN_REQUEST';
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
export const LOGIN_FAILURE = 'LOGIN_FAILURE';

export const GET_USER_REQUEST= 'GET_USER_REQUEST';
export const GET_USER_SUCCESS= 'GET_USER_SUCCESS';
export const GET_USER_FAILURE = 'GET_USER_FAILURE';

export const LOGOUT = 'LOGOUT';

action

import axios from "axios";
import { API_BASE_URL } from "../../config/apiConfig";
import { GET_USER_FAILURE, GET_USER_REQUEST, GET_USER_SUCCESS, LOGIN_FAILURE, LOGIN_REQUEST, LOGIN_SUCCESS, LOGOUT, REGISTER_FAILURE, REGISTER_REQUEST, REGISTER_SUCCESS } from "./ActionType";
import { toast } from "react-toastify";

const registerRequest = () => ({ type: REGISTER_REQUEST });
const registerSuccess = (user) => ({ type: REGISTER_SUCCESS, payload: user });
const registerFailure = (error) => ({ type: REGISTER_FAILURE, payload: error });

export const register = (userData) => async (dispatch) => {
    dispatch(registerRequest());
    try {
        const response = await axios.post(`${API_BASE_URL}/auth/signup`, userData);
        const user = response.data;
        if (user.token) {
            localStorage.setItem('token', user.token);
        }
        // dispatch({ type: 'REGISTER_SUCCESS', payload: user });
        dispatch(registerSuccess(user.token));
        toast.success(user.message, {
            autoClose: 2000,
            pauseOnHover: false,
        });

    } catch (error) {
        
        dispatch(registerFailure(error.response.data.error));
        toast.error(error.response.data.error, {
            autoClose: 2000,
            pauseOnHover: false,
        });
    }
}


const loginRequest = () => ({ type: LOGIN_REQUEST });
const loginSuccess = (user) => ({ type: LOGIN_SUCCESS, payload: user });
const loginFailure = (error) => ({ type: LOGIN_FAILURE, payload: error });

export const login = (userData) => async (dispatch) => {
    dispatch(loginRequest());
    try {
        const response = await axios.post(`${API_BASE_URL}/auth/signin`, userData);
        const user = response.data;
        if (user.token) {
            localStorage.setItem('token', user.token);
        }
        toast.success(user.message, {
            autoClose: 2000,
            pauseOnHover: false,
        });
        dispatch(loginSuccess(user.token));

    } catch (error) {
        toast.error(error.response.data.error, {
            autoClose: 2000,
            pauseOnHover: false,
        });
        dispatch(loginFailure(error.message));
    }
}


const getUserRequest = () => ({ type: GET_USER_REQUEST });
const getUserSuccess = (user) => ({ type: GET_USER_SUCCESS, payload: user });
const getUserFailure = (error) => ({ type: GET_USER_FAILURE, payload: error });

export const getUser = () => async (dispatch) => {
    dispatch(getUserRequest());
    try {
        const response = await axios.get(`${API_BASE_URL}/users/profile`, {
            headers: {
                'Authorization': `Bearer ${localStorage.getItem('token')}`
            }
        });
        const user = response.data;
        dispatch(getUserSuccess(user));

    } catch (error) {
        dispatch(getUserFailure(error.message));
    }
}


export const logout = () => async (dispatch) => {
    localStorage.clear();
    toast.success("Logged out successfully", {
        autoClose: 2000,
        pauseOnHover: false,
    });
    dispatch({ type: LOGOUT, payload: null });
}

reducer

const initialState = {
    user: null,
    error: null,
    loading: false,
    jwt: null
}


export const authReducer = (state = initialState, action) => {
    switch (action.type) {
        case 'LOGIN_REQUEST':
        case 'REGISTER_REQUEST':
        case 'GET_USER_REQUEST':
            return {
                ...state,
                error: null,
                loading: true,
            }
        case 'LOGIN_SUCCESS':
        case 'REGISTER_SUCCESS':
            return {
                ...state,
                error: null,
                loading: false,
                jwt: action.payload
            }
        case 'GET_USER_SUCCESS':
            return {
                ...state,
                error: null,
                loading: false,
                user: action.payload
            }
        case 'LOGIN_FAILURE':
            return {
                ...state,
                error: action.payload.error,
                loading: false,
            }
        case 'LOGOUT':
            return initialState
        default:
            return state
    }
}

I don’t know what is the issue I am facing.
I tried for straight 3-4 days but couldn’t find the solution to this redirecting issue

I tried all the related issues in redux and that they all are working perfectly as expected but why is this issue occurring

I removed all the errors and warnings in the console.
Then every possible error removed them

2

Answers


  1. If you are using older version of react router dom try adding exact to the home page path

    <Route exact path='/' element={<HomePage />} />
    Login or Signup to reply.
  2. You haven’t provided enough information to be able to help provide a proper implementation that could help solve the issue you’re experiencing but I’m hoping this probable solution of mine is enough to help you overcome your issues.

    First of all, I noticed you’re saving your token to local storage, but you’re not retrieving it in your application to be able to handle secure and protected routes. Therefore, when you refresh your page, the jwt state gets lost and you get redirected to the home page which is an accessible route. I’m going to implement a PrivateRoute component that can be wrapped around all the pages you’re expecting users to not be able to access unless they have been properly authenticated.

    //PrivateRoute.jsx
    
    import React from "react";
    import { Navigate, useLocation, Outlet } from "react-router-dom";
    import { useSelector } from "react-redux";
    
    const PrivateRoute = ({ ...rest }) => {
      const token = useSelector((state) => state.auth.jwt); //This is pointing to the jwt state property of your reducer
    
      const location = useLocation();
    
      if (token) {
        return <Outlet {...rest} />;
      }
    
      return <Navigate to="/login" state={{ from: location }} />;
    };
    
    export default PrivateRoute;
    
    

    You can import the PrivateRoute to the CustomRoute you have defined. I have also refactored the CustomRoute for better structure.

    export default function CustomRoutes() {
      return (
        <div>
          <div>
            <Navbar />
          </div>
          <Routes>
            <Route path="/">
              <Route index element={<HomePage />} />
              <Route path="login" element={<HomePage />} />
              <Route path="register" element={<HomePage />} />
            </Route>
            <Route element={<PrivateRoute />}>
              <Route path="/">
                <Route path="products">
                  <Route index element={<div>Product Page</div>} />
                  <Route
                    path=":productId"
                    element={<div>Product Details Page</div>}
                  />
                </Route>
                <Route path="cart" element={<Cart />} />
                <Route path="checkout" element={<Checkout />} />
                <Route path="account">
                  <Route index element={<p>Account Page</p>} />
                  <Route path="order">
                    <Route index element={<p>Order Page</p>} />
                    <Route path=":orderId" element={<p>Order Page</p>} />
                  </Route>
                </Route>
                <Route path="payment">
                  <Route index element={<p>Payment Page</p>} />
                  <Route path=":orderId" element={<p>Payment Success</p>} />
                </Route>
              </Route>
            </Route>
          </Routes>
          <div>
            <Footer />
          </div>
        </div>
      );
    }
    

    This implies that all the pages wrap around the PrivateRoute component would not be accessible unless jwt state is true. While other pages outside the PrivateRoute would become a public route and can be accessed even if the user isn’t authenticated.

    Also, you might need to initialize your jwt reducer state with the value of the token saved in the local storage. This way, if there is already an existing token in the local storage, your current page would persist even if it’s a protected route.

    const initialState = {
        user: null,
        error: null,
        loading: false,
        jwt: localStorage.getItem("token") || null
    }
    

    I hope this helps in solving your current issues.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search