Home > Blockchain >  React - Warning: Cannot update a component (`PrivateRoute`) while rendering a different component (`
React - Warning: Cannot update a component (`PrivateRoute`) while rendering a different component (`

Time:05-16

Getting the following error on all child components.

react-dom.development.js:86 Warning: Cannot update a component (PrivateRoute) while rendering a different component (Example). To locate the bad setState() call inside Examples,

I've found lots of examples of the same error but thus far no solutions React Route Warning: Cannot update a component (`App`) while rendering a different component (`Context.Consumer`) Can Redux cause the React warning "Cannot update a component while rendering a different component"

The PrivateRoute wraps the component to redirect if not logged in.

export default function PrivateRoute() {
  const session: ISessionReducer = useSelector((state: RootState) => state.core.session);

  useEffect(() => {
    if (!session.jwt) <Navigate to="/login" />;
  }, [session]);

  return <Outlet />;
};

CodePudding user response:

It is happening because useEffect runs after the component is rendered. So what's happening in this case is that your Outlet component is getting rendered first before your code in useEffect runs. So if the jwt token doesn't exist then it will try to redirect but it won't be able to because your Outlet will already be rendered by then.

So I can give you the solution of what I use to check if the jwt token exist.

1.) I create a custom hook for checking if the token exists.
2.) And then I use that custom hook in my privateRoute component to check if the user is loggedIn.

useAuthStatus.js

import { useState, useEffect } from 'react'
import { useSelector } from 'react-redux'

export const useAuthStatus = () => {
  const [loggedIn, setLoggedIn] = useState(false)
  const [checkingStatus, setCheckingStatus] = useState(true)

  const { user } = useSelector((state) => state.auth)

  useEffect(() => {
    if (user?.token) {
      setLoggedIn(true)
    } else {
      setLoggedIn(false)
    }

    setCheckingStatus(false)
  }, [user?.token])

  return { loggedIn, checkingStatus }
}

PrivateRoute component

import { Navigate, Outlet } from 'react-router-dom'
import { useAuthStatus } from '../../hooks/useAuthStatus'
import CircularProgress from '@mui/material/CircularProgress'

const PrivateRoute = () => {
  const { loggedIn, checkingStatus } = useAuthStatus()

  if (checkingStatus) {
    return <CircularProgress className='app__modal-loader' />
  }

  return loggedIn ? <Outlet /> : <Navigate to='/login' />
}

export default PrivateRoute
  • Related