简体   繁体   中英

Setting state in react useEffect not happening before gets to the route

app.js


    const [isLoggedIn, setIsLoggedIn] = useState(false);

    useEffect(() => {
        
        fetch('http://localhost:5000/usersystem/user/isloggedin', {
            method: 'GET',
            credentials: 'include',
            mode: 'cors'
        }).then(response => response.json())
        .then(response => {
            setIsLoggedIn(response.success);
        })

    }, []);

    return (
        <div className="App">
            <AppContext.Provider value={{ isLoggedIn, setIsLoggedIn }}>
                <Routes />
            </AppContext.Provider>
        </div>
    );
}

routes.js

export default function Routes() {
    return (
        <Switch>
            <ProtectedRoute exact path="/">
                <Dashboard />
            </ProtectedRoute>
            <Route exact path="/login">
                <Login />
            </Route>
            <Route>
                <Notfound />
            </Route>
        </Switch>
    );
}

protectedroute.jsx

import React from "react";
import { Route, Redirect, useLocation } from "react-router-dom";
import { useAppContext } from "../libs/ContextLib";

export default function ProtectedRoute({ children, ...rest }) {
  const { pathname, search } = useLocation();
  const { isLoggedIn } = useAppContext();
    
  return (
    <Route {...rest}>
      {isLoggedIn ? (
        children
      ) : (
        <Redirect to={
          `/login?redirect=${pathname}${search}`
        } />
      )}
    </Route>
  );
}

I have a node express app on port 5000, which handles user authentication with passport and cookie session. It works all good, the session cookies gets to the browser, and can read it and can send it back to authenticate the user.

However, in react, when i refresh the browser the user gets redirected to the login page instead of the dashboard, even with the session cookies in the browser.

It feels like the setIsLoggedIn(response.success) in app.js, wont update isLoggedIn before it gets to the ProtectedRoute and redirects to login.

Im into this for 4 hours now, and couldnt solve it. Can someone please suggest me a way to do this, or tell me what is the problem, so when i refresh the page it wont redirect to login? Thanks.

Your component is rendered once when you create the component. Your setIsLoggedIn will update the state and re-render it. You could put in a Loader to wait for the data to come before displaying the page you want. Eg:

function MyComponent () {
   const [isLoggedIn, setIsLoggedIn] = useState(null);

    useEffect(() => {
        
        fetch('http://localhost:5000/usersystem/user/isloggedin', {
            method: 'GET',
            credentials: 'include',
            mode: 'cors'
        }).then(response => response.json())
        .then((response, err) => {
            if(err) setIsLoggedIn(false); // if login failure
            setIsLoggedIn(response.success);
        })
        

    }, []);

    if(isLoggedIn === null) return (<div>Loading</div>);

    // this is only rendered once isLoggedIn is not null
    return (
        <div className="App">
            <AppContext.Provider value={{ isLoggedIn, setIsLoggedIn }}>
                <Routes />
            </AppContext.Provider>
        </div>
    );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM