it-swarm.com.de

Was bedeutet der Fehler "JSX-Elementtyp '...' hat keine Konstrukt- oder Aufrufsignaturen"?

Ich habe Code geschrieben:

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

Ich erhalte eine Fehlermeldung:

Der JSX-Elementtyp Elem hat keine Konstrukt- oder Aufrufsignaturen

Was heißt das?

110
Ryan Cavanaugh

Dies ist eine Verwechslung zwischen Konstruktoren und Instanzen.

Beachten Sie Folgendes, wenn Sie eine Komponente in React schreiben:

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

Sie benutzen es so:

return <Greeter whoToGreet='world' />;

Du nicht benutze es so:

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

Im ersten Beispiel übergeben wir Greeter, die Konstruktorfunktion für unsere Komponente. Das ist die richtige Verwendung. Im zweiten Beispiel übergeben wir ein Instanz von Greeter. Das ist falsch und schlägt zur Laufzeit mit einem Fehler wie "Objekt ist keine Funktion" fehl.


Das Problem mit diesem Code

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

erwartet ein Instanz von React.Component. Was Sie wollen, ist eine Funktion, die einen Konstruktor für React.Component Benötigt:

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

oder ähnlich:

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

Wenn Sie eine Komponentenklasse als Parameter (gegen eine Instanz) verwenden möchten, verwenden Sie React.ComponentClass:

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

Wenn ich von JSX nach TSX konvertiere und einige Bibliotheken als js/jsx und andere als ts/tsx konvertiere, vergesse ich fast immer, die js/jsx-Importanweisungen in den TSX\TS-Dateien von zu ändern

import * as ComponentName from "ComponentName";

zu

import ComponentName from "ComponentName";

Wenn Sie eine alte JSX-Komponente (React.createClass) aus TSX aufrufen, verwenden Sie

var ComponentName = require("ComponentName")

27
Michael

Wenn Sie sich wirklich nicht für Requisiten interessieren, ist der breiteste mögliche Typ React.ReactType.

Dadurch könnten native dom-Elemente als Zeichenfolge übergeben werden. React.ReactType deckt all dies ab:

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

Wenn Sie material-ui verwenden, gehen Sie zur Typdefinition der Komponente, die von TypeScript unterstrichen wird. Höchstwahrscheinlich werden Sie so etwas sehen

export { default } from './ComponentName';

Sie haben zwei Möglichkeiten, um den Fehler zu beheben:

1.Fügen Sie .default Hinzu, wenn Sie die Komponente in JSX verwenden:

import ComponentName from './ComponentName'

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

2.Nennen Sie die Komponente, die als "Standard" exportiert wird, beim Import:

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

const Component = () => <ComponentName />

Auf diese Weise müssen Sie nicht jedes Mal .default Angeben, wenn Sie die Komponente verwenden.

3
Eduard