I’m attempting to integrate this package into an app using this example. I’m not too familiar with typescript and I see that it uses interface
in one of the utils (which javascript does not have). I’ve read Does JavaScript have the interface type (such as Java’s ‘interface’)?, but I’m not sure this is the same as the one typescript uses.
Here’s the TS code I am trying to convert:
import * as React from 'react' import { Route, Redirect, RouteComponentProps } from 'react-router-dom' import type { RouteProps } from 'react-router-dom' import { useKeycloak } from '@react-keycloak/web' interface PrivateRouteParams extends RouteProps { component: | React.ComponentType<RouteComponentProps<any>> | React.ComponentType<any> } export function PrivateRoute({ component: Component, ...rest }: PrivateRouteParams) { const { keycloak } = useKeycloak() return ( <Route {...rest} render={(props) => keycloak?.authenticated ? ( <Component {...props} /> ) : ( <Redirect to={{ pathname: '/login', state: { from: props.location }, }} /> ) } /> ) }
Here’s what someone suggested for JS:
import * as React from 'react'; import { Route, Redirect } from 'react-router-dom'; import { useKeycloak } from '@react-keycloak/web'; export function PrivateRoute({ component, ...rest }) { const { keycloak } = useKeycloak(); return ( <Route {...rest} render={(props) => keycloak?.authenticated ? ( <Component {...props} /> ) : ( <Redirect to={{ pathname: '/auth', state: { from: props.location }, }} /> ) } /> ); }
Still, I don’t think that <Component />
will work in react.js.
EDIT: Added code
Advertisement
Answer
React Router takes a prop component
with a lowercase c
. In order to call a custom component using JSX it must have an uppercase name. See the docs
The Typescript example code renamed the prop component
to Component
when destructuring it. That allows them to call <Component />
using JSX.
When converting the code to Javascript you accidentally removed this renaming. You probably mistook it for a type annotation.
This code should work:
import * as React from 'react' import { Route, Redirect } from 'react-router-dom' import { useKeycloak } from '@react-keycloak/web' export function PrivateRoute({ component: Component, ...rest }) { const { keycloak } = useKeycloak() return ( <Route {...rest} render={(props) => keycloak?.authenticated ? ( <Component {...props} /> ) : ( <Redirect to={{ pathname: '/login', state: { from: props.location }, }} /> ) } /> ) }