简体   繁体   中英

Redirect user after login with react redux?

I'm using react redux with Next.js and I want to redirect the user to a certain page if he matches the requirement. I added it in my useEffect and it works, but every time when I go back to the home page it redirects again to the same page. It works fine If I refresh the page which is going to clear the redux state.

useEffect(() => {
    const validateUser = (services: ServiceType[]) => {
      if (services.length === 0) {
        router.push('/dashboard/expert/onboard');
      } else {
        router.push(
          '/dashboard/expert/[expertname]?view=overview',
          `/dashboard/expert/${userProfile.expertProfile.name}?view=overview`
        );
      }
    };
    if (userProfile) {
      if (userProfile.isVerified) {
        if (nextPath && nextPath.as) {
          router.push(nextPath.href, nextPath.as);
        } else if (userProfile.isExpert) {
          setModalVisible(false);
          if (services) {
            validateUser(services);
          }
          // setAlreadySignedUpModalVisible(true);
        } else if (loginResponse && loginResponse.expertApplications.rejected > 0) {
          setModalVisible(false);
          setApplicationRejectedModalVisible(true);
        } else if (loginResponse && loginResponse.expertApplications.pending > 0) {
          setModalVisible(false);
          setApplicationReceivedModalVisible(true);
          setIsPendingExpert(true);
        } else {
          if (nextPath) {
            router.push(nextPath.href);
          }
          setModalVisible(false);
        }
      } else {
        setModalVisible(false);
        setEmailVerifyModalVisible(true);
      }
    }
  }, [
    loginResponse,
    setAlreadySignedUpModalVisible,
    setApplicationReceivedModalVisible,
    setApplicationRejectedModalVisible,
    setEmailVerifyModalVisible,
    setModalVisible,
    userProfile,
    nextPath,
    setIsPendingExpert,
    services,
  ]);

I understand you want to redirect at the moment when the user logged in and is validated.

That is reacting to some specific event, so you need some kind of " event handler ".

useEffect is not an event handler , useEffect is for "keeping state synchronized".

So useEffect in your case wants to redirect whenever the app has a specific state, which is given no matter if the user has just logged in or already was logged in earlier.
(eg note that useEffect always gets called at least once when the component is loaded the first time, so that the state is initially synchronized.)

solution 1

It is possible to kind of "map" and event to the state by including the moment-it-happended into the state. This is not always trivial, because "it just happended" means "nothing contradictive happened since then" , and you might not be able to monitor (or even know about) all conflicting events.

So, your event-state is not only "logged in and is validated" . I think you could describe the needed state like:
" login state has changed since user is on page AND is logged in AND is valid "

Eg

const [ hasLoggedInSinceOnPage, setHasLoggedInSinceOnPage ] = useState(false);
...
loginRequest.then( (xyz)=>{
    yourLoginCode(xyz);
    setHasLoggedInSinceOnPage(true);
});
...
useEffect(()=>{
    setHasLoggedInSinceOnPage(false);
}, [ currentPage ]);

Another idea would be a state like wasRedirectedAlready .

solution 2

I would try, if possible, to call the router.push directly as a consequence of the login event (ie not using useEffect). That probably requires some redesign of the code. It also might sometimes be not possible in a clean way (I'm not absolutely sure about that).

Eg:

loginRequest.then( (xyz)=>{
    validate(xyz).then( (isValid)=>{
        router.push('...');
    });
});

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