0

I build an app in React and I try to make a dynamic routing, but my app doesn't wait for the useEffect to end.

What I want to do here is to send to my backend an object from localStorage, check it and send it back to frontend. If the result is true, when I type "/form" I want to go to "/form" route, but if is false I want to send him back to "/login".

I tried to use useState and a message while my useState is working but is not usefull...

When I'm logged in and I try to go to '/form', my app see that my useStates are false and redirect me to "/login" automatically and doesn't wait for my fetch to end...

How can I fix that?

import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom';
import Login from './views/Login';
import Logout from './views/Logout';
import AddUser from './views/AddUser';
import Movies from './views/Movies';
import Table_data from './components/Table_data';
import NavbarMenu from './views/NavbarMenu';
import { useSelector, useDispatch } from 'react-redux';
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
import { useEffect, useState } from 'react';
import { globalRequestParameters, url } from './utils';


function App() {
  const dispatch = useDispatch();
  const data = useSelector((state) => state.users.data);
  const [loggedIn, setLoggedIn] = useState(false);
  const [finishedCheking, setFinishedChecking] = useState(false);

  useEffect(() => {
    if (!data.length) {
      let requestParameters = globalRequestParameters;
      fetch(url + 'users', requestParameters)
        .then(res => res.json()
          .then(res => {
            if (res.message) {
              dispatch({ type: 'setUsers', payload: res.data })
            }
          })
        )
    }

    if (localStorage.getItem('is_logged_in')) {
      let check_loggedIn = JSON.parse(localStorage.getItem('is_logged_in'));
      let requestParam = globalRequestParameters;
      requestParam.method = 'POST';
      requestParam.headers.Authorization = JSON.stringify(check_loggedIn);
      fetch(url + 'check', requestParam)
          .then(res => res.json()
              .then(res => {
                  if (res.loggedIn === true) {
                    setLoggedIn(true);
                    setFinishedChecking(true);
                  }
              })
          )
    }
      
  }, [])

  return (
    <div>
      <NavbarMenu />
      {finishedCheking === false ? 
        <div>Loading...</div>
        :
        loggedIn === false ? 
        <Router>
          <Routes>
            <Route exact path="/" element={<Table_data />} />
            <Route exact path="/login" element={<Login />} />
            <Route exact path="/logout" element={<Logout />} />
            <Route exact path="/form" element={<AddUser />} />
            <Route exact path="/movies" element={<Movies />} />
          </Routes>
        </Router>
        :
        <Router>
        <Routes>
          <Route exact path="/" element={<Table_data />} />
          <Route exact path="/login" element={<Login />} />
          <Route exact path="/logout" element={<Logout />} />
          <Route exact path="/form" element={<Navigate replace to="/login" />}/>
          <Route exact path="/movies" element={<Movies />} />
        </Routes>
      </Router>
      }
    </div>
  );
}

export default App;

1
  • 1
    It looks like you've inverted the condition, shouldn't loggedIn be true to render the "/form" route that renders AddUser, and false should render the redirect? Commented May 18, 2022 at 9:01

2 Answers 2

1

Wrap both of your Routers with {finishedChecking === true ? {both routers} : <></>}. Inside promise .then change the value of finishedChecking to true. After change of state the jsx will be rendered once more and go inside the condition and you will be sure there that you have your promise resolved. If you need more than one condition then you can stack them up {finishedChecking === true && anotherVariable === true ? {both routers} : <> </>} and change them inside other promises.

Sign up to request clarification or add additional context in comments.

Comments

0

That is because fetch has then which is a promise, meaning that it will resolve it when it's done and get back to it at that time.
To solve this, you need to const res = fetch(url + 'users', requestParameters) and use it further in the same manier

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.