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
If you are using older version of react router dom try adding exact to the home page path
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.You can import the
PrivateRoute
to the CustomRoute you have defined. I have also refactored the CustomRoute for better structure.This implies that all the pages wrap around the
PrivateRoute
component would not be accessible unlessjwt
state istrue
. While other pages outside thePrivateRoute
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.I hope this helps in solving your current issues.