Search code examples
node.jsreactjsexpressexpress-session

How to Redirect in React based on State


I'm using useEffect to get the login state of user if (userLoggedIn === false) then I want to redirect instantly to the login route, otherwise show the dashboard.

My problem is that the Dashboard is showing for a split second then the Redirecting happens! I tested the userLoggedIn in the console.log and it prints two times the first time the value is undefined, then it prints false...

I think this happening because the value of state is (userLoggedIn) is not set in the first place, but even when I set it to false for example it does the exact same thing..

I'm getting the (userLoggedIn) value using a useEffect from a backend, my code is: -

import { useState, useEffect } from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Redirect
} from "react-router-dom";
import Axios from "axios";

import ModalNotFound from "../../components/Modal/ModalNotFound";

//views
import Home from "./views/Home";
import Menu from "./views/Menu";
import Orders from "./views/Orders";
import AddFood from "./views/AddFood";
import EditFood from "./views/EditFood";
import About from "./views/About";

const DashboardContainer = () => {
  document.body.classList.add("dashboard");

  const [userLoggedIn, setUserLoggedIn] = useState(false);

  Axios.defaults.withCredentials = true;

  useEffect(() => {
    Axios.get("http://dev.com:3001/login")
      .then(({ data }) => setUserLoggedIn(data.loggedIn))
      .catch((err) => console.error(err));

    return () => setUserLoggedIn(); // cleanup: set the value to nothing
  }, []);

  console.log(userLoggedIn);

  return (
    <>
      {userLoggedIn === false ? (
        <Redirect to='/login' />
      ) : (
        <Router>
          <Switch>
            <Route exact strict path='/dashboard' component={Home} />
            {/* if user accesses /dashboard/ then remove ending slash / bcuz it messes the links*/}
            <Route exact strict path='/dashboard/'>
              <Redirect to='/dashboard' />
            </Route>
            <Route exact strict path='/dashboard/menu' component={Menu} />
            <Route exact strict path='/dashboard/orders' component={Orders} />
            <Route
              exact
              strict
              path='/dashboard/add-food'
              component={AddFood}
            />
            <Route
              exact
              strict
              path='/dashboard/edit-food'
              component={EditFood}
            />
            <Route exact strict path='/dashboard/about' component={About} />

            <Route path='*' component={ModalNotFound} />
          </Switch>
        </Router>
      )}
    </>
  );
};

export default DashboardContainer;

and for the EndPoint/Back-end (http://dev.com:3001/login) I'm using this code: -

module.exports = (req, res) => {
  if (req.session.user) {
    res.send({ loggedIn: true, user: req.session.user });
  } else {
    res.send({ loggedIn: false });
  }
};

Solution

  • As you said the console.log prints two times and the first time userLoggedIn is undefined. It's here that the dashboard is showing since userLoggedIn is not equal to false it goes to the code that displays the dashboard.

    To prevent the first render, you can wrap your return

    return (
            { userLoggedIn !== undefined && {/* your code */} }
           );