Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async Route Element Return in React JS

Getting Error: Guard(...): Nothing was returned from render. This usually means a return statement is missing.

I want to call the API in my guard component before returning the element to Route Element to check if the logged in user have access to specific route or not.

For that, I have implemented a guard. Here's the route file code.

export default function Router() {
    return (
        <Routes>
            <Route path="organizations">
                <Route path="list" element={<Guard><ListOrganization /></Guard>} />
        </Routes >
    );
}

Guard component code

const Guard = (props) => {
    fetch('https://apiToCheckPermission.com')
    .then(response => {
        if (response.isPermission) {
            return props.children;
        }
    })
};

export default Guard;

It's kind of a thing that, I want to implement async route element. But React is throwing error if I don't immediately return the element from Guard.

Can anyone please tell How to solve this error?

like image 747
Chris T Avatar asked May 11 '26 04:05

Chris T


2 Answers

If Guard is supposed to be a React component then it needs to always return valid JSX. The Guard currently returns nothing. I.E. it would need to return something from the Promise chain and then return that from the function body.

To resolve use some local state to hold a confirmed/verified permission value and conditionally render the children prop or a fallback. A typical route protection implementation will wait to confirm a user's access then render either the children or redirect to the login page with the location being accessed so the user can be redirected back after authenticating.

Example:

const Guard = ({ children }) => {
  const location = useLocation();

  const [hasPermission, setHasPermission] = React.useState(); // <-- initially undefined

  React.useEffect(() => {
    );
    fetch('https://apiToCheckPermission.com')
      .then(response => {
        setHasPermission(response.isPermission);
      });
  }, []);

  if (hasPermission === undefined) {
    return null; // or loading indicator, spinner, etc
  }

  return hasPermission
    ? children
    : <Navigate to="/login" replace state={{ from: location }} />;
};
like image 71
Drew Reese Avatar answered May 13 '26 19:05

Drew Reese


Try to define a state to handle the permission and useEffect to load the data:

const Guard = (props) => {
  const [hasPermission, setHasPermission] = useState(false);

  useEffect(() => {
    const fetchPermission = async () => {
        const response = await fetch('https://apiToCheckPermission.com');
        setHasPermission(response.isPermission);
    }
    
    fetchPermission().catch(console.error);
  }, []);

  if (!hasPermission) return <>Unauthorized</>;

  return props.children;
};

export default Guard;
like image 42
lpizzinidev Avatar answered May 13 '26 17:05

lpizzinidev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!