Anetellie
Anetellie

Reputation: 333

PrivateRoute wait for response

Im trying to make my privateRoute wait for my API calls. to determine if the user is online and allowed to the page or not. but im getting the following error:

error:

Error: PrivateRoute(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.

i think its not waiting for a response to render since im waiting for my server. How do i solve so it wait?

im calling it like this:

server response privateroute:

import React from 'react';
import PropTypes from 'prop-types';
import { Route, Navigate } from 'react-router-dom';
import { useNavigate  } from "react-router-dom";
import Login from './components/login/login.jsx';
import GameComponent from './gameComponent.jsx';
import axios from 'axios';

const PrivateRoute = ({ component: Component, redirectTo, isAuth, path, ...props }) => {
    //isAuth = false;
    axios.post(`http://localhost:3000/online`,{withCredentials: true})
      .then(res => {
        console.log(res);
       
       if (res) {
           isAuth = true;
       } else {
           isAuth = false;
       }
       
       
        if(!isAuth) {
            return <Navigate to={redirectTo} />;
        }
        return <Route path={path} element={<Component />} />
        
      });
};

export default PrivateRoute;

old code:

const PrivateRoute = ({ component: Component, redirectTo, isAuth, path, ...props }) => {
    //isAuth = false;
    // no code checking... or real auth
            if(!isAuth) {
            return <Navigate to={redirectTo} />;
        }
        return <Route path={path} element={<Component />} />
        
};

export default PrivateRoute;

update: Remember it has to work with React-route Version 6

Upvotes: 2

Views: 418

Answers (1)

Martin J
Martin J

Reputation: 2159

You will find my intake here : https://codesandbox.io/s/react-router-basic-forked-m0624?file=/private.js (see the private.js file, I made a private route for the topic route (topics button))

Your first mistake is that your PrivateRoute component is not returning anything. You would have to do return axios.post to return at least something (that what gives the error).

Then as axios.post is an async function that takes some time to resolve, nothing is rendered from PrivateRoute while it is fetching so you have to make sure that PrivateRoute is at least returning a loading component while it fetches.

if (isLoading) return <div>loading</div>;

Then in your following code, React wont do anything if you change variable like that. (so it won't "react" to the change)

           isAuth = true;
       } else {
           isAuth = false;
       }

You have to make a hook function like this let [isAuth, setIsAuth] = React.useState(false) and changing the variable like this setIsAuth(true). In my solution I made a custom hook for isAuth and isLoading to get and set the variables and so that React can react to their change and render the good component.

Upvotes: 2

Related Questions