“JSX 요소 유형 '…'에 구성 또는 호출 서명이 없습니다. '오류는 무엇을 의미합니까?


158

나는 약간의 코드를 썼다 :

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

오류가 발생했습니다 :

JSX 요소 유형에 Elem구성 또는 호출 서명이 없습니다.

무슨 뜻인가요?

답변:


196

이것은 생성자인스턴스 사이의 혼동 입니다.

React에서 컴포넌트를 작성할 때 다음을 기억하십시오.

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

이 방법으로 사용하십시오.

return <Greeter whoToGreet='world' />;

당신은 하지 않는 것이이 방법을 사용합니다 :

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

첫 번째 예에서는 컴포넌트 Greeter생성자 함수 인 을 전달 합니다. 올바른 사용법입니다. 두 번째 예에서는의 인스턴스 를 전달 합니다Greeter . 올바르지 않으며 런타임시 "개체가 함수가 아닙니다"와 같은 오류로 실패합니다.


이 코드의 문제

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

인스턴스 를 기대하고 있다는 것 입니다 React.Component. 생성자 를 취하는 함수 React.Component:

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

또는 유사하게 :

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

31
이 글을 쓰는 시점에서, 당신이 @types/react그것들을 사용한다면 가장 사용하기 쉽다function RenderGreeting(Elem: React.ComponentType) { ... }
Jthorpe

궁금한 점 function renderGreeting(Elem: typeof React.Component)은 ES6로 어떻게 작성 합니까?
Bruce Sun

감사. 상태 비 저장 기능 구성 요소를 전달하려면 어떻게됩니까? 나는 생각 function renderGreeting (Elem: new() => React.SFC<any>){...}왜 우리가 이런 식으로 된 SFC의 유형을 선언 않도록 경우 const Hello:React.SFC<any> = (props) => <div>Hello World</div>, 그리고 :const Hello: new() =>React.SFC<any> = (props) => <div>Hello World</div>
벤 잉어

1
@Jthorpe 귀하의 의견은 해당 IMO에서 답변하고 받아 들여야합니다.
Tomáš Hübelbauer 오전

export const BackNavigationTextWrapper = (WrappedComponent: typeof React.Component) => { const BackNavigationTextWrappedComponent = (props, { commonElements = {} }: any) => { return <WrappedComponent {...props} backLabel={commonElements.backLabel || 'Go back to reservation details'} /> }; BackNavigationTextWrappedComponent.type = WrappedComponent.type; return BackNavigationTextWrappedComponent; }; "typeof Component '유형에"Property'type '이 없습니다. "오류가 발생합니다.
Prakash P

60

컴포넌트 클래스를 매개 변수 (인스턴스)로 사용하려면 React.ComponentClass다음을 사용하십시오 .

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

이제 기능적인 구성 요소가 혼합 된 경우 해당 React.ComponentType<any>유형을 포함하는 대신 유형을 사용해야 합니다.

34

JSX에서 TSX로 변환하고 일부 라이브러리를 js / jsx로 유지하고 다른 라이브러리를 ts / tsx로 변환 할 때 TSX \ TS 파일의 js / jsx import 문을 변경하는 것을 거의 항상 잊어 버립니다.

import * as ComponentName from "ComponentName";

import ComponentName from "ComponentName";

TSX에서 이전 JSX (React.createClass) 스타일 컴포넌트를 호출하는 경우

var ComponentName = require("ComponentName")


4
나는 당신이 다른 길을 의미한다고 생각합니까?
apieceofbart

5
TypeScript (예 : in tsconfig.json)를로 구성하면 inport 문을 변경할 필요가 없습니다 allowSyntheticDefaultImports. 참조 : typescriptlang.org/docs/handbook/compiler-options.html 및 토론 : blog.jonasbandi.net/2016/10/…
jbandi

11

소품에 관심이 없다면 가장 넓은 유형은 React.ReactType입니다.

네이티브 dom 요소를 문자열로 전달할 수 있습니다. React.ReactType이 모든 것을 다룹니다 :

renderGreeting('button');
renderGreeting(() => 'Hello, World!');
renderGreeting(class Foo extends React.Component {
   render() {
      return 'Hello, World!'
   }
});

8

material-ui를 사용하는 경우 TypeScript에서 밑줄이있는 구성 요소의 유형 정의로 이동하십시오. 아마도 당신은 이와 같은 것을 보게 될 것입니다

export { default } from './ComponentName';

오류를 해결하는 두 가지 옵션이 있습니다.

1. JSX .default에서 컴포넌트를 사용할 때 추가하십시오.

import ComponentName from './ComponentName'

const Component = () => <ComponentName.default />

가져올 때 "기본"으로 내보내는 구성 요소의 이름을 바꿉니다.

import { default as ComponentName } from './ComponentName'

const Component = () => <ComponentName />

이 방법으로 .default구성 요소를 사용할 때마다 지정할 필요가 없습니다 .


1
이것은 내 문제를 해결하는 데 도움이되었습니다.
WhiteWalker


2

필자의 경우 React.ReactNode유형 대신 기능 구성 요소의 React.FC유형으로 사용하고있었습니다.

이 구성 요소에서 정확히 :

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>
      }
    />
  )
}


2

@Jthorpe가 언급 된 바와 같이, ComponentClass단 하나 수 있습니다 Component또는 PureComponent아니지만 FunctionComponent.

을 전달하려고하면 FunctionComponenttypescript와 비슷한 오류가 발생합니다.

Type '(props: myProps) => Element' provides no match for the signature 'new (props: myProps, context?: any): Component<myProps, any, any>'.

그러나 두 가지 경우 모두를 허용 하는 ComponentType대신 사용하십시오 ComponentClass. 반응 선언 파일에 따라 유형은 다음과 같이 정의됩니다.

type ComponentType<P = {}> = ComponentClass<P, any> | FunctionComponent<P>

2

제 경우 new에는 유형 정의 내부에서 누락되었습니다 .

some-js-component.d.ts 파일:

import * as React from "react";

export default class SomeJSXComponent extends React.Component<any, any> {
    new (props: any, context?: any)
}

그리고 tsx형식화되지 않은 구성 요소를 가져 오려고했던 파일 내부 :

import SomeJSXComponent from 'some-js-component'

const NewComp = ({ asdf }: NewProps) => <SomeJSXComponent withProps={asdf} />

2

React Class 컴포넌트를 선언 할 때 React.ComponentClass 대신 사용 React.Component하면 ts 오류가 해결됩니다.


1

당신이 사용할 수있는

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

그러나 다음은 작동합니까?

function renderGreeting(Elem: React.ComponentType) {
    const propsToPass = {one: 1, two: 2};

    return <span>Hello, <Elem {...propsToPass} />!</span>;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.