What does the error “JSX element type '…' does not have any construct or call signatures” mean?

后端 未结 13 2151
余生分开走
余生分开走 2020-11-28 02:05

I wrote some code:

function renderGreeting(Elem: React.Component) {
    return Hello, !;
}


        
相关标签:
13条回答
  • 2020-11-28 02:33

    In my case, I was using React.ReactNode as a type for a functional component instead of React.FC type.

    In this component to be exact:

    export const PropertiesList: React.FC = (props: any) => {
      const list:string[] = [
        ' Consequat Phasellus sollicitudin.',
        ' Consequat Phasellus sollicitudin.',
        '...'
      ]
    
      return (
        <List
          header={<ListHeader heading="Properties List" />}
          dataSource={list}
            renderItem={(listItem, index) =>
              <List.Item key={index}> {listItem } </List.Item>
          }
        />
      )
    }

    0 讨论(0)
  • 2020-11-28 02:34

    This is a confusion between constructors and instances.

    Remember that when you write a component in React:

    class Greeter extends React.Component<any, any> {
        render() {
            return <div>Hello, {this.props.whoToGreet}</div>;
        }
    }
    

    You use it this way:

    return <Greeter whoToGreet='world' />;
    

    You don't use it this way:

    let Greet = new Greeter();
    return <Greet whoToGreet='world' />;
    

    In the first example, we're passing around Greeter, the constructor function for our component. That's the correct usage. In the second example, we're passing around an instance of Greeter. That's incorrect, and will fail at runtime with an error like "Object is not a function".


    The problem with this code

    function renderGreeting(Elem: React.Component<any, any>) {
        return <span>Hello, <Elem />!</span>;
    }
    

    is that it's expecting an instance of React.Component. What you want is a function that takes a constructor for React.Component:

    function renderGreeting(Elem: new() => React.Component<any, any>) {
        return <span>Hello, <Elem />!</span>;
    }
    

    or similarly:

    function renderGreeting(Elem: typeof React.Component) {
        return <span>Hello, <Elem />!</span>;
    }
    
    0 讨论(0)
  • 2020-11-28 02:35

    If you are passing functional component as props to anyother component use following:

    import React from 'react';
    
    type RenderGreetingProps = {
      element: React.FunctionComponent<any>
    };
    
    function RenderGreeting(props: RenderGreetingProps) {
      const {element: Element} = props;
    
      return <span>Hello, <Element />!</span>;
    }
    
    0 讨论(0)
  • 2020-11-28 02:37

    You can use

    function renderGreeting(props: {Elem: React.Component<any, any>}) {
        return <span>Hello, {props.Elem}!</span>;
    }
    

    However, does the following work?

    function renderGreeting(Elem: React.ComponentType) {
        const propsToPass = {one: 1, two: 2};
    
        return <span>Hello, <Elem {...propsToPass} />!</span>;
    }
    
    0 讨论(0)
  • 2020-11-28 02:37

    I solved it by making use of Type Assertions before exporting the component. TypeScript wasn't able to identify after composing it using redux 'compose' therefore I divided props types into IParentProps and IProps and use IParentProps while doing Type Assertions

    import { compose } from 'react-redux'
    import HOC1 from 'HOCs/HOC1'
    import HOC2 from 'HOCs/HOC2'
    
    type IParentProps = {}
    type IProps = {}
    
    const Component: React.FC<IProps & IParentProps> = React.memo((props) => {
    
          return <SomeComponent {...props}/>
    
    })
    
    return compose(HOC1,HOC2)(Component) as React.FunctionComponent<IParentProps>
    
    0 讨论(0)
  • 2020-11-28 02:39

    If you want to take a component class as a parameter (vs an instance), use React.ComponentClass:

    function renderGreeting(Elem: React.ComponentClass<any>) {
        return <span>Hello, <Elem />!</span>;
    }
    
    0 讨论(0)
提交回复
热议问题