1

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

Etep
  • 2,721
  • 4
  • 17
  • 28
  • 3
    If i understand correctly, you're writing javascript and want to know how to use the package? You should just need to run `npm install --save @react-keycloak/web`. Code that was written in typescript transpiles to javascript, so it should work seamlessly. – Nicholas Tower Mar 12 '21 at 02:22
  • 1
    If you still need help, please provide the code you've tried. Links to code don't cut it, as they'll likely go stale. – Heretic Monkey Mar 12 '21 at 02:26

1 Answers1

2

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 },
            }}
          />
        )
      }
    />
  )
}
Linda Paiste
  • 38,446
  • 6
  • 64
  • 102