Home > OS >  Can't Wrap a Route Component with an HOC (ReactJS)
Can't Wrap a Route Component with an HOC (ReactJS)

Time:01-09

Hey I can't wrap my Route Component with an HOC. I am using react-router-dom v6 but I'm not able to make this work

Here is my implementation:

<Route path="/dashboard" element={AuthGuard(<Dashboard />)} />

HOC:

import React from "react";
import { Navigate } from "react-router-dom";
import { firebase } from "../firebase";

    const AuthGuard = (Component) => {
      class AuthHoc extends React.Component {
        authCheck = () => {
          const user = firebase.auth().currentUser;
          console.log("USER:: ", user);
          if (user) {
            return <Component {...this.props} />;
          } else {
            return <Navigate to="/" />;
          }
        };
        render() {
          return this.authCheck();
        }
      }
      return AuthHoc;
    };
    
    export default AuthGuard;

and I get this error:

Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it

CodePudding user response:

Just like the error says you are placing a function as a react child. So the element actually needs to be a valid react component. If you return valid jsx then you can probably run the function first and then place it in the routes element prop. Also your AuthGuard function can be greatly simplified. Like so:

import Dashboard from './Dashboard'

const AuthGuard = (Component) => (props) => {
  const user = firebase.auth().currentUser;
  console.log("USER:: ", user);

  return user ? <Component {...props} /> : <Navigate to="/" />;
}

const Dash = AuthGuard(Dashboard)

<Route path="/dashboard" element={<Dash />} />

Or you can just wrap the dashboard in your AuthGuard before exporting it like :

export default AuthGuard(Dashboard)

But if you want to place the AuthGuard in the element prop of the route then you will have to make it a component so you can either wrap the protected component like so:

<Route path="/dashboard" element={<AuthGuard><Dashboard /></AuthGuard>)} />

and then your AuthGuard component would look like:

const AuthGuard = ({children}) => {
  const user = firebase.auth().currentUser;
  console.log("USER:: ", user);

  return user ? children : <Navigate to="/" />;
}

Or you can Do something like the following and pass a component in as props.

const AuthGuard = ({Component}) => {
  const user = firebase.auth().currentUser;
  console.log("USER:: ", user);

  return user ? Component : <Navigate to="/" />;
}

<Route path='/dashboard' element={<AuthGuard Component={<Dashboard />} />}/>
  •  Tags:  
  • Related