Definitelytyped: Menerapkan defaultProps dengan pemeriksaan nol ketat ts 2.0

Dibuat pada 30 Sep 2016  ·  50Komentar  ·  Sumber: DefinitelyTyped/DefinitelyTyped

Properti default tampaknya tidak berfungsi dengan baik saat ini dengan strictNullChecks diaktifkan. Sebagai contoh:

interface TestProps { x?: number}

class Test extends React.Component<TestProps, null> {

    static defaultProps =  {x: 5};

    render() {
        const x: number = this.props.x;
        return <p>{x}</p>;
    }
}

Kesalahan dengan error TS2322: Type 'number | undefined' is not assignable to type 'number' meskipun ini dijamin berfungsi saat runtime.

Saat ini defaultProps dan Props tampaknya selalu diperlakukan sebagai tipe yang sama, tetapi sebenarnya hampir tidak pernah menjadi tipe yang sama karena bidang opsional di Props harus ditimpa oleh nilai yang diperlukan di DefaultProps.

Bagaimana jika ada sesuatu seperti...

class ComponentWithDefaultProps<P, D, S> {
    props: P & D & {children?: React.Children};
}

yang identik dengan pengetikan React.Component yang ada kecuali untuk jenis props?

Komentar yang paling membantu

Jika ada yang punya solusi bagus untuk tipe dan defaultProps, saya siap. Saat ini kami melakukan ini:

interface Props {
  firstName: string;
  lastName?: string;
}

interface DefaultProps {
  lastName: string;
}

type PropsWithDefaults = Props & DefaultProps;

export class User extends React.Component<Props> {
  public static defaultProps: DefaultProps = {
    lastName: 'None',
  }

  public render () {
    const { firstName, lastName } = this.props as PropsWithDefaults;

    return (
      <div>{firstName} {lastName}</div>
    )
  }
}

Semua 50 komentar

Karena alat peraga default disetel saat runtime, saya tidak yakin apakah ada cara untuk menangani ini dengan baik, selain pernyataan tipe. (Tentu saja, Anda selalu dapat menonaktifkan pemeriksaan nol yang ketat.)

Inilah cara Anda dapat menyiasatinya dalam contoh Anda:

interface TestProps { x?: number}

class Test extends React.Component<TestProps, null> {

    static defaultProps =  {x: 5};

    render() {
        const x: number = (this.props.x as number);
        return <p>{x}</p>;
    }
}

Lihat https://www.typescriptlang.org/docs/handbook/basic-types.html#type -assertions

Jika ada cara yang lebih anggun untuk menangani ini, saya akan senang mendengarnya.

Penafian: Saya telah menggunakan TypeScript selama sekitar tiga hari, saya lelah, dan mungkin tidak tahu apa yang saya bicarakan.

+1000 untuk memperbarui file definisi tipe untuk menyertakan tiga definisi tipe umum.

Ini dulu baik-baik saja tanpa ---strictNullChecks , tapi sekarang, ini pasti akan menjadi masalah bagi banyak kelas komponen.

Flow juga mengimplementasikan implementasi kelas yang serupa karena sifat pemeriksaan tipe null yang ketat.
https://github.com/facebook/flow/blob/master/lib/react.js#L16
https://github.com/facebook/flow/blob/master/lib/react.js#L104 -L105

Sepertinya kami tidak memiliki banyak opsi di sini kecuali menunggu https://github.com/Microsoft/TypeScript/issues/2175 diselesaikan untuk menambahkan generik ketiga.
Saya tidak berpikir bahwa perubahan (melanggar) seperti itu (maksud saya class Component<P, S, D> ) dapat disetujui oleh pengulas.
@johnnyreilly @bbenezech @pzavolinsky apakah kalian punya pendapat tentang itu?

@r00ger setuju. Mengubah definisi terlalu mengganggu.

Adakah yang pernah mempertimbangkan untuk menggunakan Partial ?

Seperti dalam:

    interface ComponentClass<P> {
-        defaultProps?: P;
+        defaultProps?: Partial<P>;
    }

Jangan pedulikan hal Partial di atas.

Partial hanya memecahkan bagaimana mendeklarasikan masalah propTypes parsial. Di dalam render , lastName masih bertipe string | undefined . Untuk menyiasatinya, Anda harus melemparkan string menggunakan as atau ! seperti yang ditunjukkan di bawah ini. Ini bekerja, tetapi tidak ideal.

interface IUser {
    firstName: string
    lastName?: string
}
export class User extends React.Component<IUser, {}> {
    public static defaultProps: Partial<IUser> = {
        lastName: 'None',
    }

    public render () {
        const { firstName, lastName } = this.props
        // error
        lastName.toUpperCase()

        return (
            <div>{firstName} {lastName}</div>
        )
    }
}

Saya baru mulai menggunakan TS. Apakah saya kehilangan sesuatu?

Jika ada yang punya solusi bagus untuk tipe dan defaultProps, saya siap. Saat ini kami melakukan ini:

interface Props {
  firstName: string;
  lastName?: string;
}

interface DefaultProps {
  lastName: string;
}

type PropsWithDefaults = Props & DefaultProps;

export class User extends React.Component<Props> {
  public static defaultProps: DefaultProps = {
    lastName: 'None',
  }

  public render () {
    const { firstName, lastName } = this.props as PropsWithDefaults;

    return (
      <div>{firstName} {lastName}</div>
    )
  }
}

+1
Saat ini saya sedang berjuang melawan masalah ini.

+1

+1

Selain menambahkan parameter tipe ketiga, Anda memerlukan kemampuan untuk membedakan props dengan props default. Untungnya pada TS 2.4 ini sekarang mungkin! Lihat https://github.com/Microsoft/TypeScript/issues/12215#issuecomment -319495340

IMHO menambahkan parameter ketiga adalah tidak, tidak, juga tim Flow tahu itu dan baru-baru ini mereka mengubahnya untuk kebaikan yang lebih besar. Seharusnya menjadi tanggung jawab pemeriksa tipe untuk mengetahui bagaimana menangani hal-hal semacam ini.

Jangan salah paham, saya suka TypeScript, tetapi karena Flow 0.53 saya harus mengatakan itu lebih unggul untuk pengembangan React https://medium.com/flow-type/even-better-support-for-react-in-flow- 25b0a3485627

@Hotell Flow memang memiliki tiga parameter tipe untuk React.Component - per artikel Medium yang Anda tautkan ke Flow dapat menyimpulkan parameter tipe kelas dari anotasi subkelas - fitur tingkat bahasa yang rapi TS tidak mendukung, tetapi bukan tipe -pertimbangan deklarasi AFAIK.

@aldendaniels

Flow memang memiliki tiga parameter tipe untuk React.Component

tidak, dulu seperti itu sebelum 0,53, tidak lagi :) https://github.com/facebook/flow/commit/20a5d7dbf484699b47008656583b57e6016cfa0b#diff -5ca8a047db3f6ee8d65a46bba4471236R29

@Hotell Ah, tentu saja! Terima kasih telah mengoreksi saya.

AFAIK tidak ada cara di TS untuk menyimpulkan jenis alat peraga default. Dengan menggunakan pendekatan tiga tipe parameter, kami mungkin bisa mendapatkan pengetikan yang benar tanpa memblokir perubahan upstream dari tim TypeScript.

Apakah Anda mengetahui cara untuk menggunakan tipe kesimpulan dari properti statis tanpa melewatkan typeof MyComponent.defaultProps sebagai parameter tipe?

Ada berita tentang hal ini? Apakah seseorang melakukan PR untuk menambahkan parameter tipe ketiga dan menggunakan https://github.com/Microsoft/TypeScript/issues/12215#issuecomment -319495340?

Masalah upvoting: masalah yang sama

+1

Saya juga mengalami ini, dan saya telah memilih (sampai ini diperbaiki dengan benar) untuk tidak menggunakan static defaultProps dan sebagai gantinya menggunakan helper HOC:

Komponen file/pembantu/withDefaults.tsx :

import * as React from 'react'

export interface ComponentDefaulter<DP> {
  <P extends {[key in keyof DP]?: any}>(Component: React.ComponentType<P>): React.ComponentType<
    Omit<P, keyof DP> &         // Mandate all properties in P and not in DP
    Partial<Pick<P, keyof DP>>  // Accept all properties from P that are in DP, but use type from P
  >
}

export default function withDefaults<DP>(defaultProps: DP): ComponentDefaulter<DP> {
  return Component => props => <Component {...defaultProps} {...props}/>
}

Sekarang saya dapat menggunakan:

Komponen file/Button.tsx :

import * as React from 'react'
import withDefaults from './helpers/withDefaults'

export interface ButtonProps {
  label: string
  onPress: () => any
}

export const defaultProps = {
  onPress: () => undefined
}

class Button extends React.Component<ButtonProps> {
  // ...
}

export default withDefaults(defaultProps)(Button)

Tiga potensi kerugian (yang dapat saya pikirkan):

  1. Itu membutuhkan HOC, tetapi karena ini adalah paradigma yang cukup umum di dunia React, itu sepertinya OK.
  2. Anda harus mendeklarasikan props sebagai parameter tipe generik, dan tidak dapat mengandalkan inferensi dari properti props .
  3. Tidak ada pemeriksaan implisit dari jenis defaultProps , tetapi ini dapat diatasi dengan menentukan export const defaultProps: Partial<ButtonProps> = {...} .

Menurut @vsaarinen , saya menulis kelas dasar dengan props: Props & DefaultProps , sehingga seluruh kelas yang memperluas kelas dasar dapat langsung menggunakan this.props tanpa menggunakan this.props as PropsWithDefaults .

Seperti ini:

import * as React from 'react'

export class Component<P = {}, S = {}, DP = {}> extends React.Component<P, S> {
  props: Readonly<{ children?: React.ReactNode }> & Readonly<P> & Readonly<DP>
}

export interface Props {
  firstName: string
  lastName?: string
}

export interface DefaultProps {
  lastName: string
}

export class User extends Component<Props, any, DefaultProps> {
  render() {
    const { firstName, lastName } = this.props

    // no error
    return (
      <div>{firstName} {lastName.toUpperCase()}</div>
    )
  }
}

Sebenarnya @ qiu8310 itu tidak berfungsi sepenuhnya, Masih ada masalah dengan situs panggilan yang berteriak tentang alat peraga default yang tidak opsional. Berfungsi dengan sedikit penyesuaian

import * as React from 'react'

export class Component<P = {}, S = {}, DP = {}> extends React.Component<P, S> {
  // Cast the props as something where readonly fields are non optional
  props = this.props as Readonly<{ children?: React.ReactNode }> & Readonly<P> & Readonly<DP>
}

export interface Props {
  firstName: string
  lastName?: string
}

export interface DefaultProps {
  lastName: string
}

export class User extends Component<Props, any, DefaultProps> {
  render() {
    const { firstName, lastName } = this.props

    // no error
    return (
      <div>{firstName} {lastName.toUpperCase()}</div>
    )
  }
}

Saya bermain dengan generik ketiga dan akhirnya memiliki sesuatu yang mirip dengan proposal @ qiu8310 :

// ComponentWithDefaultProps.ts
import * as React from "react";

export declare class ComponentWithDefaultProps<P, S, DP extends Partial<P>> extends React.Component<P & DP, S> {}
type redirected<P, S, DP> = ComponentWithDefaultProps<P, S, DP>;
const redirected: typeof ComponentWithDefaultProps = React.Component as any;

export const Component = redirected;

// User.ts
import { Component } from "ComponentWithDefaultProps";
export interface Props {
  firstName: string
  lastName?: string
}
export interface DefaultProps {
  lastName: string
}

export class User extends Component<Props, {}, DefaultProps> {
  public render() {
    const { firstName, lastName } = this.props;
    return <div>{firstName} {lastName.toUpperCase()}</div>;
  }
}

Namun kedua pendekatan ini (milik saya dan pendekatan di atas) menyebabkan masalah yang lebih besar. Ada jenis komponen yang dibuat dalam contoh saya:

User: React.ComponentClass<P & DP>
User["props"]: Readonly<{ children?: React.ReactNode }> & Readonly<P & DP>

Rupanya, antarmuka User salah. React.ComponentClass<P & DP> berarti lastName juga diperlukan, sehingga

<User firstName="" />;
//    ~~~~~~~~~~~~  Property 'lastName' is missing...

Dalam tipe contoh @ qiu8310 berbeda:

User: React.ComponentClass<P>
User["props"]: Readonly<{ children?: React.ReactNode }> & Readonly<P> & Readonly<DP>

Tetapi bagian JSX yang sama menyebabkan kesalahan yang sama, karena tsc 's JSX checks didasarkan pada props ' type .

<User firstName="John" />;
//    ~~~~~~~~~~~~~~~~  Property 'lastName' is missing...

Hal yang menyenangkan adalah <User firstName="John" /> diubah menjadi React.createElement(User, {firstName: "John"}) yang akan menjadi TypeScript yang valid. Dalam hal ini pemeriksaan tipe bergantung pada parameter tipe pertama ComponentClass , jadi

<User firstName="Jonh" />; // doesn't work, but
React.createElement(User, { firstName: "John" }); // works

Seperti yang Anda lihat, meskipun memiliki generik ketiga, kami masih harus menambahkan trik lain untuk mengekspor komponen dengan antarmuka yang benar:

export const User = class extends Component<Props, {}, DefaultProps> {
    // ...
} as React.ComponentClass<Props>;

<User firstName="Jonh" />; // works

Jadi memiliki obat generik ketiga tidak masuk akal.

Tampaknya tidak ada solusi bagus yang dapat digabungkan ke definisi React , untuk saat ini saya tetap menggunakan ComponentWithDefaultProps dan menegaskan jenis komponen yang diekspor.

export interface DefaultProps {
    lastName: string;
}
export interface Props extends Partial<DefaultProps> {
    firstName: string;
}

export type PropsWithDefault = Props & DefaultProps;

export const User: as React.ComponentClass<Props> =
class extends React.Component<PropsWithDefault> {
    render() {
        // no error
        return <div>
            {this.props.firstName}
            {this.props.lastName.toUpperCase()}
        </div>;
    }
};
// Note, we've assigned `React.Component<PropsWithDefault>` to `React.ComponentClass<Props>`

Selain itu Anda dapat menegaskan setiap penggunaan this.props ketik metode komponen (misalnya const { lastName } = this.props as Props & DefaultProps , atau menggunakan tanda seru di mana-mana this.props.lastName!.toLowerCase() ).

saya menemukan beberapa contoh tentang diskusi ini - https://github.com/gcanti/typelevel-ts#objectdiff

@rifler yang disebut pendekatan HOC (saya lebih suka dekorator) telah ada di sini untuk sementara waktu , kami mencoba memberikan solusi yang tidak menambahkan overhead runtime

Oh bagus
Semoga Anda akan menemukan solusinya

Adakah peningkatan?

Berikut adalah variasi dari teknik yang disebutkan oleh @r00ger :

interface IUser {
    name: string;
}
const User = class extends React.Component<IUser> {
    public static defaultProps: IUser = {name: "Foo"}
    public render() {
        return <div>{this.props.name}</div>;
    }
} as React.ComponentClass<Partial<IUser>>;
React.createElement(User, {}); // no error, will output "<div>Foo</div>"

Menggunakan cuplikan di atas akan berfungsi, tetapi Anda akan kehilangan kemampuan untuk menggunakan properti statis pada Pengguna, karena itu menjadi kelas anonim. Solusi peretasan adalah dengan membayangi nama kelas, seperti:

// tslint:disable-next-line:no-shadowed-variable
const User = class User extends React.Component<IUser>

Anda sekarang dapat menggunakan bidang statis pribadi di dalam kelas. Statika publik masih tidak dapat digunakan. Juga, perhatikan kebutuhan untuk membungkam tslint.

Saya pikir perlu disebutkan bahwa pada TS 2.8, tipe Exclude didukung secara resmi:

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;

Lihat https://github.com/Microsoft/TypeScript/pull/21847.

Jadi yang kita butuhkan hanyalah React.createElement() untuk meminta yang berikut ini sebagai pengganti Props :

Omit<Props, keyof DefaultProps>

Satu-satunya masalah adalah bahwa dalam deklarasi React, tidak ada tipe DefaultProps - untuk ini kita memerlukan parameter tipe ketiga ATAU kemampuan untuk menyimpulkan tipe anggota statis sebagai fitur bahasa.

Sementara itu, kami telah bergulir dengan yang berikut:

/**
 * The Create type allow components to implement a strongly thed create() function
 * that alows the caller to omit props with defaults even though the component expects
 * all props to be populated. The TypeScript React typings do not natively support these.
 */
export type Create<C extends BaseComponent<any, any>, D extends {} = {}> = (
  props?: typeHelpers.ObjectDiff<C['props'], D> & React.ClassAttributes<C>,
  ...children: React.ReactNode[]
) => React.ComponentElement<any, any>;

export interface DomPropsType {
  domProps?: domProps.DomProps;
}

export class BaseComponent<P, S = {}> extends React.Component<P & DomPropsType, S> {
  static create(props?: object, ...children: React.ReactNode[]) {
    return React.createElement(this, props, ...children);
  }

  constructor(props: P & DomPropsType, context?: any) {
  ...
}

Dan semua komponen kami terlihat seperti:

export class InsertObjectMenu extends BaseComponent<Props, State> {
  static create: Create<InsertObjectMenu, typeof InsertObjectMenu.defaultProps>;
  static defaultProps = {
    promptForImageUpload: true,
  };
  ...
}

Terakhir, kita memiliki aturan lint yang memberlakukan bahwa atribut create dideklarasikan pada semua komponen. Kami tidak menggunakan JSX, jadi kami menggunakan:

InsertObjectMenu.create({...})

Alih-alih React.createElement() .

Kami telah menggunakan pendekatan ini di seluruh basis kode besar selama hampir satu tahun sekarang dengan sukses yang baik, tetapi kami ingin mengadopsi BEJ dan inilah yang menahan kami.

Begitu banyak waktu yang diinvestasikan dalam "masalah sederhana" ini. Saya akan tinggalkan ini di sini https://medium.com/@martin_hotell/ultimate -react-component-patterns-with-typescript-2-8-82990c516935

    interface Component<P = {}, S = {}, DP extends Partial<P>=P> extends ComponentLifecycle<P, S> { }
    class Component<P, S, DP extends Partial<P> = P> {
        constructor(props: P & DP, context?: any);

        // We MUST keep setState() as a unified signature because it allows proper checking of the method return type.
        // See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-351013257
        // Also, the ` | S` allows intellisense to not be dumbisense
        setState<K extends keyof S>(
            state: ((prevState: Readonly<S>, props: P) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
            callback?: () => void
        ): void;

        forceUpdate(callBack?: () => void): void;
        render(): ReactNode;

        // React.Props<T> is now deprecated, which means that the `children`
        // property is not available on `P` by default, even though you can
        // always pass children as variadic arguments to `createElement`.
        // In the future, if we can define its call signature conditionally
        // on the existence of `children` in `P`, then we should  remove this.
        private __externalProps: Readonly<{ children?: ReactNode }> & Readonly<P>;
        props: Readonly<{ children?: ReactNode }> & Readonly<P> & DP;
        state: Readonly<S>;
        context: any;
        refs: {
            [key: string]: ReactInstance
        };
    }

    class PureComponent<P = {}, S = {}, DP extends Partial<P>=P> extends Component<P, S, P> { }


interface ElementAttributesProperty { __externalProps: {}; }

Perhatikan baik-baik pada baris terakhir.

Dengan perubahan ini kita bisa memiliki

interface Props {
    a: string
    b?: string
    c?: string
}

class Comp extends React.Component<Props, {}, typeof Comp.defaultProps> {
    static defaultProps = {
        b: ''
    }

    render() {
        const {a, b, c} = this.props

        let res = a.concat(b)  // ok
        let res1 = a.concat(c) //fail

        return null
    }
}



const res1= <Comp a=''/> // ok
const res3 = <Comp /> // fail

Mana yang terbaik yang bisa kita dapatkan jika menggunakan static defaultProps (pemeriksa ts harus diubah jika kita ingin menghilangkan typeof Comp.defaultProps ).
Pilihan lain, sudah dikatakan - HOC, ketik gips.

Inilah upaya saya (sangat jelek) berdasarkan ide dari https://medium.com/@martin_hotell/ultimate -react-component-patterns-with-typescript-2-8-82990c516935:

type ExtractProps<T> = T extends React.ComponentType<infer Q> ? Q : never;
type ExtractDefaultProps<T> = T extends { defaultProps?: infer Q } ? Q : never;
type RequiredProps<P, DP> = Pick<P, Exclude<keyof P, keyof DP>>;
type RequiredAndPartialDefaultProps<RP, DP> = Required<RP> & Partial<DP>;

type ComponentTypeWithDefaultProps<T> =
  React.ComponentType<
    RequiredAndPartialDefaultProps<
      RequiredProps<ExtractProps<T>, ExtractDefaultProps<T>>,
      ExtractDefaultProps<T>
    >
  >;

function withDefaultProps<T extends React.ComponentType<any>>(Comp: T) {
  return Comp as ComponentTypeWithDefaultProps<T>;
}
interface IProps {
  required: number;
  defaulted: number;
}

class Foo extends React.Component<IProps> {
  public static defaultProps = {
    defaulted: 0,
  };
}

// Whichever way you prefer... The former does not require a function call
const FooWithDefaultProps = Foo as ComponentTypeWithDefaultProps<typeof Foo>;
const FooWithDefaultProps = withDefaultProps(Foo);

const f1 = <FooWithDefaultProps />;  // error: missing 'required' prop
const f2 = <FooWithDefaultProps defaulted={0} />;  // error: missing 'required' prop
const f3 = <FooWithDefaultProps required={0} />;  // ok
const f4 = <FooWithDefaultProps required={0} defaulted={0} />;  // ok

@decademoon , sepertinya kita bisa menggunakan solusi ini di @types/react , bukan? Maksud saya, jika kami mengganti React.ComponentType yang biasa dengan solusi Anda.
Jika demikian, mungkin Anda bisa membuat PR?

@decademoon definisi Anda tidak menangani kasus di mana alat peraga non-default sebenarnya menyertakan bidang opsional, yaitu

interface IProps {
  required: number;
  notRequired?: () => void;
  defaulted: number;
}

class Foo extends React.Component<IProps> {
  public static defaultProps = {
    defaulted: 0,
  };
}

Saya membuatnya berfungsi dalam kasus saya dengan mengubah jenis RequiredAndPartialDefaultProps Anda untuk tidak membungkus "RP" dengan "Diperlukan"

type RequiredAndPartialDefaultProps<RP, DP> = RP & Partial<DP>;

Saya terkejut masih belum ada solusi yang tepat atau setidaknya HOC yang berfungsi di NPM; kecuali saya melewatkan sesuatu.

Halo semuanya. Hanya ingin mengatakan dan jika Anda masih membaca utas ini: Saya pikir @JoshuaToenyes membuat penjelasan yang paling berarti dan bermanfaat. Ini jelas bukan masalah jadi tidak ada hubungannya dengan itu. Gunakan jenis pernyataan dalam kasus ini.

@toiletpatrol sebenarnya, solusi @decademoon (dengan sedikit perubahan saya) secara otomatis menangani props default dengan baik. Itu pasti dapat digabungkan ke dalam definisi DT untuk Bereaksi untuk menyediakan standar fitur untuk semua orang.

@toiletpatrol @RobRendell apakah Anda melihatnya https://github.com/Microsoft/TypeScript/issues/23812?

@vkrol Saya memang melihatnya, tetapi saya dapat menghapus implementasi dekademoon di basis kode saya sekarang tanpa menunggu rilis fitur baru.

Solusi lain yang saya gunakan untuk saat ini untuk kasus-kasus rumit:

const restWithDefaults = { ...Component.defaultProps, ...rest };
return <Component {...restWithDefaults} />;

Saya kira tidak ada yang salah dengan itu, jadi saya meninggalkannya di sini sebagai solusi yang kotor namun sederhana.

TS 3.2 dan reaksi 16.7 pengetikan memperbaiki ini. bisakah kita tutup?

@Hotell bagaimana itu harus ditangani pada akhirnya? Saya masih tidak bisa membuat ini berfungsi dengan baik

Untuk menghemat waktu orang lain, berikut ini tautan ke catatan rilis TypeScript 3:
Dukungan untuk defaultProps di JSX

@cbergmiller Saya khawatir itu adalah catatan rilis untuk TypeScript 3.1

masih memiliki masalah yang sama dengan React.FunctionComponent

@denieler Saya tidak menyarankan menggunakan defaultProps dengan React.FunctionComponent , itu tidak alami. Lebih baik menggunakan parameter fungsi default:

interface HelloProps {
  name?: string;
  surname?: string;
}

const HelloComponent: React.FunctionComponent<HelloProps> = ({
  name = 'John',
  surname = 'Smith',
}) => {
  return <div>Hello, {name} {surname}!</div>
};

@mgol Bagaimana Anda mendefinisikan parameter fungsi default jika saya tidak ingin merusak alat peraga?
Saya hanya bisa memikirkan untuk merusak hanya properti "default" seperti:

interface HelloProps {
  name?: string;
  surname?: string;
}

const HelloComponent: React.FunctionComponent<HelloProps> = ({
  name = 'John',
  surname = 'Smith',
  ...props
}) => {
  return <div>Hello, {name} {surname}! You are {props.age} years old.</div>
};

Tapi saya merasa memalukan untuk mengekstrak hanya beberapa alat peraga.

@glecetre Anda dapat menggunakan:

HelloComponent.defaultProps = {
    name: 'John',
    surname: 'Smith'
}

@Glinkis tolong, perhatikan https://github.com/reactjs/rfcs/pull/107/files#diff -20b9b769068a185d90c23b58a2095a9dR184.

@glecetre Mengapa Anda tidak ingin merusak semua alat peraga? Ini lebih sederhana daripada mendefinisikan defaultProps & lebih mudah untuk mengetik. Jenis props komponen berbasis kelas mungkin menggigit Anda jika Anda mengekspor untuk digunakan secara eksternal karena props yang diperlukan mungkin tidak diperlukan lagi jika ada entri untuk mereka di defaultProps . Menggunakan defaultProps juga tampak sedikit ajaib saat dalam perusakan parameter semuanya adalah JavaScript.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat