I am building a React redux app which on login updates the redux initialState. Based on the user type stored in redux certain routes are enabled. Unfortunately the state mutation of redux seems to be not fast enough, since on redirect from the login the route is not available. I tried various timeouts, which - however - did not work.
Here you have an excerpt from my authSlice in redux
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import {} from '../services/auth.service';
const initialState = {
loggedIn: false,
userData: {}
};
export const loginAsync = createAsyncThunk(
'auth/login',
async (credentials) => {
return await login(credentials);
}
);
export const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
},
extraReducers: (builder) => {
builder
.addCase(loginAsync.fulfilled, (state, action) => {
state.userData = action.payload.userData;
state.loggedIn = true;
})
},
});
export const selectIsLoggedIn = (state) => state.auth.loggedIn;
export const selectUserData = (state) => state.auth.userData;
export const selectUserType = (state) => state.auth.userData.userType;
export default authSlice.reducer;
The login component looks the following
import React, {useEffect, useState} from "react";
import {Link, Redirect} from 'react-router-dom';
import {selectIsLoggedIn, selectUserType, loginAsync, selectUserData, setUserData} from "../../../slice/authSlice";
import { useDispatch, useSelector } from "react-redux";
import { history } from "../../../helpers/history";
import '../../../styles/main/Login.css';
const Login = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
//Change handlers
const changeEmail = (e) => {
setEmail(e.target.value);
};
const changePassword = (e) => {
setPassword(e.target.value);
};
/**
* @function (01) prevent the default form behaviour and set to loading
* (02) dispatch the login
* (03) redirect based on user type
*/
const performLogin = (e) => {
//01
e.preventDefault();
setLoading(true);
//02
dispatch(loginAsync({email: email, password: password}))
.then((res) => {
//03
res.payload.userData.userType === 'student' ? history.push("/student/search/") : res.payload.userType === 'coder' ? history.push("/coder/editor/") : history.push("/admin/invite/");
window.location.reload();
})
.catch(() => {
setLoading(false);
});
};
return (
<div className="login_wrapper">
login npx stuff...
</div>
);
};
export default Login;
The Routes are based on a use selector redux operation where I obtain the loggedin state and user type. This routes component is directly included in the App component. If I set the initialState to the respective states (loggedin true and usertype = student) everything works fine.
Any help is highly appreciated