Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flow React: Cannot create element because React.Component [1] is not a React component

I just started to make use of flow a few weeks ago and from a week ago i've been getting a flow error on which i've no idea how to fix.

The code goes like this:

// @flow

import React, { Component } from "react";
import { Redirect, Route } from "react-router-dom";
import CookieStorage from "./../services/CookieStorage";
import type { Component as ComponentType } from "react";

type Props = {
    component: ComponentType<any, any>
}

class ProtectedRoute extends Component<Props> {
    render() {
        const isAuthenticated     = this.isAuthenticated();
        const {...props}          = this.props;
        const AuthorizedComponent = this.props.component;

        return (
            <Route
                {...props}
                render={props => (
                    isAuthenticated ?
                        <AuthorizedComponent {...props} /> :
                        <Redirect to="/"/>
                )}
            />
        );
    }

    isAuthenticated(): boolean {
        const data = CookieStorage.get("foobar");

        return data !== null;
    }
}

export default ProtectedRoute;

In here flow throws this error:

Error:(23, 8) Cannot create `AuthorizedComponent` element because `React.Component` [1] is not a React component.

I don't know if i am doing a wrong import type or a wrong type declaration for the component that is to be rendered when the authentication example is ok.

I've copied this code from a website i don't remember where, but he was making use of this snippet using const {component: Component} = this.props and render it as <Component {...props} /> which for me it seems a little ambiguous, which is why i changed the declaration a bit to make it easy to understand when reading, but still even doing the exact same code like the snipped where i copied this code, flow still throws that error.

I've made a gist of this in case someone would knows a solution for this and would like to make a change, if no one is able to help me fix this in here, then i will send a ticket issue to their project using this gist

like image 619
Oscar Reyes Avatar asked Mar 11 '19 15:03

Oscar Reyes


1 Answers

Try to use React.ComponentType instead?

import type { ComponentType } from "react";

import React, { Component } from "react";
import { Redirect, Route } from "react-router-dom";
import CookieStorage from "./../services/CookieStorage";

type Props = {
  component: ComponentType<any>
}

class ProtectedRoute extends Component<Props> {
  render() {
    const isAuthenticated = this.isAuthenticated();
    const { component: AuthorizedComponent, ...props } = this.props;

    return (
      <Route
        {...props}
        render={props => (
        isAuthenticated ?
          <AuthorizedComponent {...props} /> :
          <Redirect to="/"/>
        )}
      />
    );
  }

  isAuthenticated(): boolean {
    const data = CookieStorage.get("foobar");
    return data !== null;
  }
}

export default ProtectedRoute;

See https://flow.org/en/docs/react/types/#toc-react-componenttype

like image 157
soywod Avatar answered Sep 28 '22 04:09

soywod