0

I'm build custom PrivateRoute for chat app. Here me PrivateRoute:

import { useState, useEffect } from 'react';
import { Route, Navigate } from 'react-router-dom';
import axios from 'axios';

interface PrivateRouteProps {
  element: React.ComponentType<any>;
  path: string;
}

export function PrivateRoute({ element: Element, path }: PrivateRouteProps) {
  const [authenticated, setAuthenticated] = useState(false);

  useEffect(() => {
    axios
      .get('http://golang:8080')
      .then((response) => {
        if (response.status === 200) {
          setAuthenticated(true);
        }
      })
      .catch((error) => {
        console.log(error);
      });
  }, []);

  return (
    <Route
      path={path}
      element={
        authenticated ? <Element /> : <Navigate to="/login" replace={true} />
      }
    />
  );
}

How I use it: <PrivateRoute path={RouterPath.ROOT} element={Main} />

Picture of my code: My code

When I build my project in console I have these errors: Screen So how to use custom PrivateRoute?

dkobzar
  • 53
  • 5

1 Answers1

1

Here is how you can change your private route component, it will only decide to render children or not, no props

import { PropsWithChildren } from 'react'

export function PrivateRoute({ children }: PropsWithChildren) {
 const [authenticated, setAuthenticated] = useState(false);
 useEffect(() => {
    axios
      .get('http://golang:8080')
      .then((response) => {
        if (response.status === 200) {
          setAuthenticated(true);
        }
      })
      .catch((error) => {
        console.log(error);
      });
  }, []);

  return <>
     authenticated ? (
        children
     ) : (
        <Navigate to="/login" replace={true} />
     )
    </>
}

Then use it that way

<Route path={path}>
  <Route path={RouterPath.ROOT} element={<PrivateRoute><Main/></PrivateRoute>}/>        
</Route>
Fateh Mohamed
  • 20,445
  • 5
  • 43
  • 52
  • Thanks, Its work perfectly, but underlined red line and says: `PrivateRoute cannot be used as a JSX component. Its return type 'string | number | boolean | ReactFragment | Element | null | undefined' is not a valid JSX element. Type 'undefined' is not assignable to type ''Element | null.` – dkobzar May 18 '23 at 11:35
  • You can wrap it in a reactFragment, let me change the answer and show you how – Fateh Mohamed May 18 '23 at 11:41
  • Can you check now, it should fix the typing problem – Fateh Mohamed May 18 '23 at 11:43
  • `authenticated` is initially false, so the redirect will ***always*** be rendered ***before*** the `useEffect` can run and check if the user is authenticated and update the `authenticated` state. This implementation is flawed. – Drew Reese May 18 '23 at 15:37
  • The answer was about router not about the whole implementation – Fateh Mohamed May 18 '23 at 19:10