skip to Main Content

I have a authState (is a boolean), it tells you if the user isLogged or it doesn’t. I have a main layout that I share with all my components. It has this logic in the useEffect

  const isLogged = useSelector(selectAuthState);
  const router = useRouter();

  useEffect(() => {
    if (isLogged) {
      router.push('/')
    }else{
      router.push('/login')
    }
  }, [isLogged])

The problem is that the default value of the selectAuthState is false, so the first render it value is false (even if in the localStorage the real value of the authState is true), in the second render the real value comes (it’s true), so my app get redirects to the ‘/’ route always because the default value of the authState is false. How can I check if the redux store ‘is ready’ or whatever I need to be sure that I have the actual redux state?

2

Answers


  1. Try to add a check to see if the Redux state has been initialized before performing the redirection:

      const isLogged = useSelector(selectAuthState);
      const router = useRouter();
      const dispatch = useDispatch();
    
      useEffect(() => {
        if (isLogged === null) {
          // You can dispatch an action to load the initial auth state from localStorage or an API here
          // dispatch(loadAuthState()); 
          // In this case, 'loadAuthState' should update the 'isLogged' state once it fetches the data
        } else {
          if (isLogged) {
            router.push('/');
          } else {
            router.push('/login');
          }
        }
      }, [isLogged, router, dispatch])
    
    Login or Signup to reply.
  2. Redux is ready when the store is created, passed to the React-Redux Provider component, and the app is mounted and rendered. There’s not really anything to check.

    The problem is that you are using initial isLogged state that matches the unauthenticated user. It is often the case that being authenticated isn’t simply a binary function, but actually a trinary function, e.g. authenticated, unauthenticated, and unknown. You should start from the unknown state if you haven’t any way to initialize the state to one of the other to "confirmed" states.

    const initialState = {
      isLogged: null, // <-- initially unknown
    };
    
    const authSlice = createSlice({
      name: "auth",
      initialState,
      reducers: { ... }
    });
    
    ...
    
    const RouteGuard = () => {
      const isLogged = useSelector(selectAuthState);
      const router = useRouter();
    
      useEffect(() => {
        // Redirect to login page only if confirmed unauthenticated
        if (isLogged === false) {
          router.replace('/login');
        }
      }, [isLogged]);
    
      ...
    
      // Authenticated not confirmed yet
      if (isLogged === null) {
        return null; // or loading indicator/spinner/etc
      }
    
      // Confirmed authentication
      return isLogged
        ? /* logged in UI */
        : null;
    };
    

    You mentioned that you have some auth state in localStorage. You may be able to initialize the state from localStorage. If there is nothing already stored then null is returned, so you’ll still want the above component logic to handle the UI.

    Example:

    const initialState = {
      isLogged: JSON.parse(localStorage.getItem("authState")), // whatever was persisted, or null
    };
    
    const authSlice = createSlice({
      name: "auth",
      initialState,
      reducers: { ... }
    });
    
    ...
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search