Wie kann man (optionale) Standard-Props mit TypeScript für zustandslose, funktionale React-Komponenten angeben?

Lesezeit: 6 Minuten

Ich versuche, eine zustandslose React-Komponente mit optionalen Props und defaultProps in Typescript zu erstellen (für ein React Native-Projekt). Dies ist mit Vanilla JS trivial, aber ich bin ratlos, wie ich es in TypeScript erreichen soll.

Mit folgendem Code:

import React, { Component } from 'react';
import { Text } from 'react-native';

interface TestProps {
    title?: string,
    name?: string
}

const defaultProps: TestProps = {
    title: 'Mr',
    name: 'McGee'
}

const Test = (props = defaultProps) => (
    <Text>
        {props.title} {props.name}
    </Text>
);

export default Test;

Berufung <Test title="Sir" name="Lancelot" /> macht “Sir Lancelot” wie erwartet, aber <Test /> führt zu nichts, wenn “Mr McGee” ausgegeben werden sollte.

Jede Hilfe wird sehr geschätzt.

  • wie wäre es mit Test.defaultProps = defaultProps ?

    – Asium

    24. Oktober 2016 um 1:02 Uhr

  • Als Nebenbemerkung: Versuchen Sie es mit Partial<Props> zur Angabe einer Teilmenge von Requisiten

    – Korvid

    21. Dezember 2017 um 15:52 Uhr

Benutzer-Avatar
Matt Stow

Hier ist eine ähnliche Frage mit einer Antwort: Reagieren Sie mit TypeScript – definieren Sie defaultProps in einer zustandslosen Funktion

import React, { Component } from 'react';
import { Text } from 'react-native';

interface TestProps {
    title?: string,
    name?: string
}

const defaultProps: TestProps = {
    title: 'Mr',
    name: 'McGee'
}

const Test: React.SFC<TestProps> = (props) => (
    <Text>
        {props.title} {props.name}
    </Text>
);

Test.defaultProps = defaultProps;

export default Test;

  • Dies ist die richtige Antwort. Kürzlich wurde SFC zugunsten von FunctionComponent verworfen: const Test: React.FunctionComponent = …

    – Lenin

    18. April 2019 um 22:26 Uhr


  • Sie können auch React.FC in Typoskript anstelle von React.FunctionComponent verwenden

    – Menschen

    13. Februar 2020 um 19:04 Uhr

  • Was ist, wenn die Eigenschaft so etwas wie ist names?: string[]? Selbst wenn ich einen Standardwert wie diesen angebe, ist er aus Sicht des Typoskripts immer noch optional, also muss ich schreiben props.names?.join(',') statt props.names.join(',')

    – Freiwind

    3. Oktober 2020 um 17:52 Uhr

  • funktioniert nur, wenn alle Requisiten optional sind

    – fullStackChris

    5. Oktober 2021 um 10:30 Uhr

  • Hallo @Lenin, das ist nicht die richtige Antwort als Angabe title und name mit ? lässt den Benutzer passieren undefined auf diese Werte, was nicht der Fall sein sollte, wenn wir die Standardwerte auf diese festgelegt haben

    – AndroidEngineX

    14. Mai um 15:50 Uhr

Benutzer-Avatar
kDar

Ich habe festgestellt, dass die einfachste Methode darin besteht, optionale Argumente zu verwenden. Beachten Sie, dass defaultProps schließlich sein wird für funktionale Komponenten veraltet.

Beispiel:

interface TestProps {
    title?: string;
    name?: string;
}

const Test = ({title="Mr", name="McGee"}: TestProps) => {
    return (
        <p>
            {title} {name}
        </p>
    );
}

  • Ja! Ein Teil der Schönheit funktionaler Komponenten besteht darin, dass Sie alle Standard-Javascript-Funktionen verwenden können.

    – Luke Miles

    3. September 2020 um 14:27 Uhr

  • Was ist, wenn der Standardwert ein Array ist? [] oder Objekt {}? Sie können nicht als Abhängigkeit von Hooks verwendet werden, da sie jedes Mal neu erstellt werden und das Ausführen des Hooks auslösen

    – Freiwind

    3. Oktober 2020 um 17:49 Uhr

  • Soweit ich weiß, sollte der Code gleich funktionieren, egal welchen Standardwert Sie eingeben. Wäre toll, wenn Sie auf Code verlinken könnten, der das Problem reproduziert, mit dem Sie sprechen [] oder {}

    – kDar

    3. Oktober 2020 um 19:27 Uhr

  • Offizielles Typoskript-Cheatsheet stimmt zu github.com/typescript-cheatsheets/react/blob/main/…

    – java-addict301

    9. Juli 2021 um 0:01 Uhr

  • funktioniert nur, wenn alle Requisiten optional sind

    – fullStackChris

    5. Oktober 2021 um 11:36 Uhr

So mache ich es am liebsten:

type TestProps = { foo: Foo } & DefaultProps
type DefaultProps = Partial<typeof defaultProps>
const defaultProps = {
  title: 'Mr',
  name: 'McGee'
}

const Test = (props: Props) => {
  props = {...defaultProps, ...props}
  return (
    <Text>
      {props.title} {props.name}
    </Text>
  )
}

export default Test

  • Das sieht toll aus, kannst du die ersten Zeilen erklären?

    – Erdal G.

    10. November 2020 um 11:22 Uhr

  • Dies ist die einzig richtige Antwort, die funktioniert, wenn die Requisiten eine Mischung aus erforderlichen und nicht erforderlichen Requisiten sind. Alle anderen Lösungen betreffen Komponenten, die nur optionale Requisiten haben.

    – fullStackChris

    5. Oktober 2021 um 10:29 Uhr

  • Ist das ein Tippfehler? Ist nicht (props: Props) soll sagen (props: TestProps)?

    – Ryan

    15. Juni um 17:44 Uhr

Wenn ich meine Lösung dem Topf hinzufüge, denke ich, dass sie den bestehenden Lösungen ein zusätzliches Maß an Lesbarkeit und Eleganz verleiht.

Nehmen wir an, Sie haben eine Komponente MyComponent mit einer Mischung aus erforderlichen und optionalen Requisiten. Wir können diese erforderlichen und optionalen Props in zwei Schnittstellen aufteilen und sie für die vollständige Prop-Schnittstelle der Komponente kombinieren, aber nur die optionale verwenden, um die Standardprops festzulegen:

import * as React from "react";

// Required props
interface IMyComponentRequiredProps {
  title: string;
}

// Optional props
interface IMyComponentOptionalProps {
  color: string;
  fontSize: number;
}

// Combine required and optional props to build the full prop interface
interface IMyComponentProps
  extends IMyComponentRequiredProps,
    IMyComponentOptionalProps {}

// Use the optional prop interface to define the default props
const defaultProps: IMyComponentOptionalProps = {
  color: "red",
  fontSize: 40,
};

// Use the full props within the actual component
const MyComponent = (props: IMyComponentProps) => {
  const { title, color, fontSize } = props;
  return <h1 style={{ color, fontSize }}>{title}</h1>;
};

// Be sure to set the default props
MyComponent.defaultProps = defaultProps;

export default MyComponent;

Benutzer-Avatar
rodrigocd

Aktualisierung 2022

Für Funktionskomponenten gibt es tatsächlich eine mögliche Abschreibung von defaultProps aufstellen. Ich glaube nicht, dass dies aufgrund der schieren Menge an Code, der bereits damit geschrieben wurde, so bald passieren wird, aber eine Warnung, die in der Konsole angezeigt wird, ist sehr wahrscheinlich.

Ich verwende die folgende Lösung, die das richtige Verhalten und die richtige TypeScript-Validierung bietet. Es funktioniert mit gemischten definierten/undefinierten Eigenschaften und auch mit Eigenschaften mit/ohne Standardwerten – das heißt, es deckt alle Fälle ab:

interface Props {
  name: string;
  surname?: string;
  age?: number;
}

const defaultProps = {
  surname: 'Doe',
};

function MyComponent(propsIn: Props) {
  const props = {...defaultProps, ...propsIn};

  return <div>{props.surname}</div>;
}

Und die automatische Vervollständigung von VSCode ist genau richtig:

VSCode-Autovervollständigung

Es wurde mit TypeScript 4.7 getestet.

Benutzer-Avatar
Frank Simon

Ich könnte mich irren, aber das Übergeben eines Standard-Prop-Werts an die Funktion, wie die zweite abgestimmte Antwort sagt, könnte zu subtilen Fehlern oder zu häufig ausgeführten useEffects führen (ich habe nicht genug Repräsentanten, um dort zu antworten, also Hier ist ein reproduzierbarer Codeanbox)

Auch wenn es sich um ein wirklich erfundenes Beispiel handelt und wahrscheinlich in den meisten Fällen nur um schlechtes Komponentendesign handelt, habe ich dies mehr als einmal gesehen und sogar ganze Seiten gebrochen.

Benutzer-Avatar
Drawwyatt

Für mich gilt das nicht sehen wie eine Typoskript-Ausgabe.

HAFTUNGSAUSSCHLUSS: Ich habe das nur mit Typoskript versucht.

Das Problem ist jedoch, dass Requisiten stets existiert (sogar als leeres Objekt, wenn nichts übergeben wird). Dafür gibt es aber 2 Workarounds.

Die erste tötet leider die supersaubere Syntax ohne geschweifte Klammern, die Sie haben, aber lassen Sie uns dabei bleiben defaultProps um.

interface TestProps {
    title?: string;
    name?: string;
}

const defaultProps: TestProps = {
    title: 'Mr',
    name: 'McGee'
}

const Test = (passedIn: TestProps) => {
    const props = Object.assign({}, defaultProps, passedIn);
    return (
        <p>
            {props.title} {props.name}
        </p>
    );
}

Eine andere Alternative, die ein wenig haarig werden könnte, wenn Sie eine TONNE von Requisiten haben, aber die es Ihnen ermöglicht, Ihre ursprüngliche Syntax beizubehalten, ist ungefähr so:

const Test = (props: TestProps) => (
    <Text>
        {props.title || 'Mr'} {props.name || 'McGee'}
    </Text>
);

Hoffe das hilft!

  • Sie müssen Object.assign nicht mit PassedIn-Requisiten und Standardwerten ausführen – das macht React automatisch.

    – Hamzu

    12. Dezember 2017 um 10:30 Uhr


  • Ihre Lösung wird wahrscheinlich funktionieren, aber sie ist falsch. Du solltest benutzen defaultProps statische Eigenschaft einer zustandslosen Komponentenfunktion zum Definieren von Standardeigenschaftswerten.

    – Tomasz Kajtoch

    26. November 2018 um 14:05 Uhr

  • @TomaszKajtoch Laut dieser Antwort defaultProps in funktionalen Komponenten abgeschrieben werden, können Sie eine Möglichkeit vorschlagen, dies ohne Verwendung zu tun defaultProps?

    – Andy Braham

    26. Oktober 2019 um 6:25 Uhr

1228150cookie-checkWie kann man (optionale) Standard-Props mit TypeScript für zustandslose, funktionale React-Komponenten angeben?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy