'React first gives null values and after a while values are initialized
I am trying to create a component to make the validation if the user is authenticated or not. It is not I am redirecting to log in, however, when I am checking if is it authenticated, first the session is null and after 2000ms says that is authenticated.
App.js
function App() {
const session = useSelector((state) => state.user.user);
useEffect(() => {
if (token) {
axios
.get(`http://localhost:4500/api/user/current`, {
headers: {
token: token,
},
})
.then((res) => {
dispatch(login(res.data));
});
} else {
dispatch(logout());
console.log("no token");
}
}, []);
console.log(session?.role + " XX S"); //first goes null and then after it is initialized
return (
<Route
element={
<RequireAuth allowedRoles={[3]} session_role={session?.role} /> //session?.role first is null and it is a problem with the logic of validation
}
>
<Route path="/protected" element={<Protected />} />
</Route>
)
RequireAuth.js
const RequireAuth = ({ allowedRoles, session_role }) => {
const session = useSelector((state) => state.user.user);
const location = useLocation();
console.log(session_role + " ROLE ");
return session_role?.find((role) => allowedRoles?.includes(role)) ? (
<Outlet />
) : session ? (
<Navigate to="/unauthorised" state={{ from: location }} replace />
) : (
<Navigate to="/login" state={{ from: location }} replace />
);
};
export default RequireAuth;
Reducer
export const userSlice = createSlice({
name: "user",
initialState: {
user: null,
isLoggedIn: false,
},
reducers: {
login: (state, action) => {
state.user = action.payload;
state.isLoggedIn = true;
},
logout: (state) => {
state.user = null;
state.isLoggedIn = false;
},
},
});
Solution 1:[1]
function App() {
const dispatch = useDispatch();
let token = 1;
useEffect(() => {
async function initializeToken() {
if (token) {
setTimeout(() => {
dispatch(login({
user: {
id: 'id',
name: 'name',
surname: 'surname',
email: 'email',
role: 'role',
},
}))
}, 2000);
} else {
dispatch(logout());
console.log("no token");
}
}
initializeToken();
}, [dispatch]);
const session = useSelector((state) => state.user);
const sessionObject = session ? JSON.parse( JSON.stringify(session)) : null ;
console.log(sessionObject, 'sessionObject');
const isAuth = sessionObject ? sessionObject.isLoggedIn : null ;
console.log(isAuth + "isAuth");
const role = sessionObject ? sessionObject.user && session.user.user ? session.user.user.role : null : null
console.log(role, 'role')
return (
<div className="App">
<Router>
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="login" element={<Login />} />
<Route exact path="unauthorised" element={<Unauthorised />} />
<Route
element={
<RequireAuth allowedRoles={[3]} session_role={session?.role} />
}
>
<Route path="/protected" element={<Protected />} />
</Route>
</Routes>
</Router>
</div>
);
}
export default App;
Have used setTimeout instead of api , it can simulate same stuff. The reason behind null is parsing the data, not the initial state i thought it would be. The above code should do the trick.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

