0

I have reading component which must show only when user is loggedIn. I now redirect the user to /login page if the user is not authenticated. But during the redirect, the reading page is displayed for a few milli seconds allowing the un-authenticated user to see a flickering of the reading page during redirection.

I tried using useLayoutEffect instead of useEffect but the same flickering happens. Also tried without using useEffect or useLayoutEffect and within a function, but still the same

I get the userInfo from a global state, which gets the userInfo from the cookie. For state management I use recoil.

Reading Page: (which must be protected and if no user, redirect to login page)

function index() {
  const router = useRouter();
  const userInfo = useRecoilValue(userAtom);   ---> userInfo is recoil global state

  useLayoutEffect(() => {
    if (!userInfo) {
      router.push("/login?redirect=/reading");
    }
  }, []);

  return (//some code)

Note: Adding a Loader worked, but is there any better way?

Sai Krishnadas
  • 2,863
  • 9
  • 36
  • 69
  • 1
    you can return nothing if has no userInfo, if (!userInfo) return null; – iamhuynq Feb 10 '22 at 06:56
  • Tried, but still useEffect runs after a render right? so, same issue is happening when given null – Sai Krishnadas Feb 10 '22 at 06:59
  • 1
    so you have to redirect in the server side, check this [question](https://stackoverflow.com/questions/54604505/redirecting-from-server-side-in-nextjs/65190232) – iamhuynq Feb 10 '22 at 08:25

2 Answers2

0
  1. Check the authentication state
  2. show loader based on authentication state
  3. Redirect the user
Ravi Varma
  • 66
  • 3
0

I would suggest a much better way. Instead of checking on individual pages.

You can write your Auth Check for user at route level i.e inside index.js where the React-Router is defined.

// PrivateRoute.jsx
function PrivateRoute ({component: Component, isAuth, ...rest}) {
  return (
    <Route
      {...rest}
      render={(props) => isAuth
        ? <Component {...props} />
        : <Redirect to={{pathname: '/login', state: {userInfo} }} />}
    />
  )
}

// index.jsx
.
const userInfo = useRecoilValue(userAtom); 
.
<Route path='/login' component={Login} />
<Route path='/register' component={Register} />
<PrivateRoute isAuth={!!userInfo} userInfo={userInfo} path='/dashboard' component={Dashboard} />
.
.

Hope this finds it helpful.

NevetsKuro
  • 604
  • 7
  • 14