web-dev-qa-db-ja.com

エラー「JSX要素タイプ '...'には構造または呼び出しシグネチャがありません」はどういう意味ですか?

私はいくつかのコードを書きました:

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

エラーが発生しています:

JSX要素タイプElemには、構成または呼び出しシグネチャがありません

どういう意味ですか?

97
Ryan Cavanaugh

これはconstructorsinstancesの間の混乱です。

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を渡します。それが正しい使い方です。 2番目の例では、Greeterinstanceを渡します。これは誤りであり、実行時に「オブジェクトは関数ではありません」などのエラーで失敗します。


このコードの問題

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>;
}
143
Ryan Cavanaugh

コンポーネントクラスをパラメーター(またはインスタンス)として使用する場合は、React.ComponentClassを使用します。

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

JSXからTSXに変換するときに、一部のライブラリをjs/jsxとして保持し、他のライブラリをts/tsxに変換するとき、TSX\TSファイルのjs/jsxインポートステートメントを変更することはほとんど忘れます

import * as ComponentName from "ComponentName";

import ComponentName from "ComponentName";

TSXから古いJSX(React.createClass)スタイルのコンポーネントを呼び出す場合は、

var ComponentName = require("ComponentName")

26
Michael

もしあなたが本当に小道具を気にしないなら、可能な限り広い型はReact.ReactTypeです。

これにより、ネイティブdom要素を文字列として渡すことができます。 React.ReactTypeはこれらすべてをカバーします:

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

material-uiを使用している場合、TypeScriptで下線が引かれているコンポーネントの型定義に移動します。ほとんどの場合、このようなものが表示されます

export { default } from './ComponentName';

エラーを解決するには2つのオプションがあります。

1. JSXでコンポーネントを使用するときに.defaultを追加します。

import ComponentName from './ComponentName'

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

2.インポート時に「デフォルト」としてエクスポートされるコンポーネントの名前を変更します。

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

const Component = () => <ComponentName />

これにより、コンポーネントを使用するたびに.defaultを指定する必要がなくなります。

2
Eduard