Definitelytyped: Implémentation de defaultProps avec ts 2.0 strict null checks

Créé le 30 sept. 2016  ·  50Commentaires  ·  Source: DefinitelyTyped/DefinitelyTyped

Les propriétés par défaut ne semblent pas bien fonctionner actuellement avec strictNullChecks activé. Par exemple:

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>;
    }
}

Erreurs avec error TS2322: Type 'number | undefined' is not assignable to type 'number' même si cela est garanti pour fonctionner à l'exécution.

À l'heure actuelle, defaultProps et Props semblent toujours être traités comme le même type, mais ils ne sont en fait presque jamais du même type, car les champs facultatifs dans Props doivent être remplacés par les valeurs requises dans DefaultProps.

Et s'il y avait quelque chose comme...

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

qui est identique au typage React.Component existant, à l'exception du type d'accessoires ?

Commentaire le plus utile

Si quelqu'un a une bonne solution pour les types et defaultProps, je suis tout ouïe. Nous faisons actuellement ceci :

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

Tous les 50 commentaires

Étant donné que les accessoires par défaut sont définis au moment de l'exécution, je ne sais pas s'il existe un moyen de gérer cela correctement, autre qu'une assertion de type. (Bien sûr, vous pouvez toujours désactiver les vérifications NULL strictes.)

Voici comment vous pouvez contourner ce problème dans votre exemple :

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>;
    }
}

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

S'il y a une manière plus élégante de gérer cela, j'aimerais l'entendre.

Avis de non-responsabilité : j'utilise TypeScript depuis environ trois jours, je suis fatigué et je n'ai probablement aucune idée de ce dont je parle.

+1000 sur la mise à jour du fichier de définition de type pour inclure trois définitions de type génériques.

Auparavant, cela fonctionnait bien sans ---strictNullChecks , mais maintenant, cela va définitivement poser problème pour de nombreuses classes de composants.

Flow implémente également une implémentation de classe similaire en raison de la nature de la vérification stricte du type null.
https://github.com/facebook/flow/blob/master/lib/react.js#L16
https://github.com/facebook/flow/blob/master/lib/react.js#L104 -L105

Il semble que nous n'ayons pas beaucoup d'options ici, sauf attendre que https://github.com/Microsoft/TypeScript/issues/2175 soit résolu afin d'ajouter un troisième générique.
Je ne pense pas qu'un tel changement (casseur) (je veux dire class Component<P, S, D> ) puisse être approuvé par les examinateurs.
@johnnyreilly @bbenezech @pzavolinsky avez-vous une opinion là-dessus ?

@r00ger a accepté. Changer la définition est trop perturbateur.

Quelqu'un a-t-il envisagé d'utiliser Partial ?

Un péché:

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

Ne vous occupez pas de ce truc Partial ci-dessus.

Partial ne résout que la façon de déclarer un problème de propTypes partiel. À l'intérieur de render , lastName est toujours de type string | undefined . Pour contourner ce problème, vous devez lancer la chaîne en utilisant as ou ! comme indiqué ci-dessous. Cela fonctionne, mais n'est pas idéal.

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

Je viens de commencer à utiliser TS. Est-ce que je manque quelque chose?

Si quelqu'un a une bonne solution pour les types et defaultProps, je suis tout ouïe. Nous faisons actuellement ceci :

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
Je lutte actuellement contre ce problème.

+1

+1

En plus d'ajouter le troisième paramètre de type, vous aurez besoin de la possibilité de différencier les props des props par défaut. Heureusement, depuis TS 2.4, c'est désormais possible ! Voir https://github.com/Microsoft/TypeScript/issues/12215#issuecomment -319495340

À mon humble avis, l'ajout d'un troisième paramètre est un gros non non, l'équipe Flow le savait également et récemment, ils l'ont changé pour le plus grand bien. Il devrait être de la responsabilité du vérificateur de type de savoir comment gérer ce genre de choses.

Ne vous méprenez pas, j'adore Typescript, mais depuis Flow 0.53, je dois dire que c'est supérieur pour le développement React https://medium.com/flow-type/even-better-support-for-react-in-flow- 25b0a3485627

@Hotell Flow a trois paramètres de type pour React.Component - selon l'article Medium que vous avez lié à Flow, vous pouvez déduire les paramètres de type de classe à partir des annotations de sous-classe - une fonctionnalité soignée au niveau de la langue que TS ne prend pas en charge, mais pas un type -déclaration considération AFAIK.

@aldendaniels

Flow a trois paramètres de type pour React.Component

non, c'était comme ça avant 0.53, plus maintenant :) https://github.com/facebook/flow/commit/20a5d7dbf484699b47008656583b57e6016cfa0b#diff -5ca8a047db3f6ee8d65a46bba4471236R29

@Hotell Ah, bien sûr ! Merci de m'avoir corrigé.

AFAIK, il n'y a aucun moyen dans TS de déduire le type des accessoires par défaut. En utilisant l'approche à trois paramètres de type, nous serions probablement en mesure d'obtenir un typage correct sans bloquer les modifications en amont de l'équipe TypeScript.

Connaissez-vous un moyen d'utiliser le type déduit d'une propriété statique sans passer typeof MyComponent.defaultProps comme paramètre de type ?

Des news à ce sujet ? Quelqu'un fait-il un PR pour ajouter un troisième paramètre de type et utiliser https://github.com/Microsoft/TypeScript/issues/12215#issuecomment -319495340 ?

Problème de vote positif : même problème

+1

J'ai également rencontré cela, et j'ai choisi (jusqu'à ce que cela soit correctement corrigé) de m'abstenir d'utiliser static defaultProps et d'utiliser à la place un assistant HOC :

Fichier composants/helpers/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}/>
}

Maintenant je peux utiliser :

Fichier composants/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)

Trois inconvénients potentiels (auxquels je peux penser):

  1. Cela nécessite un HOC, mais comme il s'agit d'un paradigme assez courant dans le monde React, cela semble correct.
  2. Vous devez déclarer les accessoires en tant que paramètre de type générique et ne pouvez pas vous fier à l'inférence de la propriété props .
  3. Il n'y a pas de vérification implicite des types de defaultProps , mais cela peut être résolu en spécifiant export const defaultProps: Partial<ButtonProps> = {...} .

Selon @vsaarinen , j'écris une classe de base avec props: Props & DefaultProps , donc toute la classe qui étend la classe de base peut utiliser directement this.props sans utiliser this.props as PropsWithDefaults .

Comme ça:

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

En fait @ qiu8310 qui ne fonctionnait pas complètement, avait toujours des problèmes avec les sites d'appel criant que ces accessoires par défaut n'étaient pas facultatifs. Je l'ai fait fonctionner avec un ajustement mineur

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

J'ai joué avec le troisième générique et j'ai fini par avoir quelque chose de similaire à la proposition de @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>;
  }
}

Cependant, ces deux approches (la mienne et l'approche ci-dessus) posent le plus gros problème. Il existe des types de composants créés dans mon exemple :

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

Apparemment, l'interface User est erronée. React.ComponentClass<P & DP> signifie que lastName est également requis, de sorte que

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

Dans l'exemple de @qiu8310 , les types sont différents :

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

Mais le même morceau de JSX provoque la même erreur, car les vérifications JSX tsc sont basées sur props ' type .

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

La chose amusante est que <User firstName="John" /> est transformé en React.createElement(User, {firstName: "John"}) qui serait un TypeScript valide. Dans ce cas, les vérifications de type reposent sur le premier paramètre de type ComponentClass , donc

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

Comme vous le voyez, même en ayant un troisième générique, nous devons encore ajouter une autre astuce afin d'exporter un composant avec une interface correcte :

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

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

Donc, avoir un troisième générique n'a pas beaucoup de sens.

Il semble qu'il n'y ait pas de bonne solution qui puisse être fusionnée à la définition de React , pour l'instant je m'en tiens à utiliser ComponentWithDefaultProps et à affirmer le type de composant exporté.

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>`

En dehors de cela, vous pouvez affirmer chaque utilisation du type this.props dans les méthodes du composant (par exemple const { lastName } = this.props as Props & DefaultProps , ou en utilisant un point d'exclamation partout this.props.lastName!.toLowerCase() ).

j'ai trouvé un exemple sur cette discussion - https://github.com/gcanti/typelevel-ts#objectdiff

@rifler soi-disant approche HOC (je préfère le décorateur) est là depuis un moment , nous essayons de trouver une solution qui n'ajoute pas de surcharge d'exécution

Oh génial
J'espère que tu trouveras la solution

aucun progrès?

Voici une variante de la technique mentionnée par @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>"

L'utilisation de l'extrait de code ci-dessus fonctionnera, mais vous perdrez la possibilité d'utiliser des propriétés statiques sur User, car il devient une classe anonyme. Une solution hacky serait d'occulter le nom de la classe, comme ceci :

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

Vous pouvez maintenant utiliser des champs statiques privés à l'intérieur de la classe. Les statiques publiques sont toujours inutilisables. Notez également la nécessité de faire taire tslint.

J'ai pensé qu'il valait la peine de mentionner qu'à partir de TS 2.8, le type Exclude est officiellement pris en charge :

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

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

Donc, tout ce dont nous avons besoin est que React.createElement() exige ce qui suit au lieu de Props :

Omit<Props, keyof DefaultProps>

Le seul problème est que dans les déclarations React, il n'y a pas de type DefaultProps - pour cela, nous avons besoin d'un troisième paramètre de type OU de la possibilité de déduire le type des membres statiques en tant que fonctionnalité du langage.

En attendant, nous avons roulé avec les éléments suivants :

/**
 * 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) {
  ...
}

Et tous nos composants ressemblent à :

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

Enfin, nous avons une règle lint imposant que l'attribut create soit déclaré sur tous les composants. Nous n'utilisons pas JSX, nous utilisons donc :

InsertObjectMenu.create({...})

Au lieu de React.createElement() .

Nous utilisons cette approche sur une grande base de code depuis près d'un an maintenant avec un bon succès, mais nous aimerions adopter JSX et c'est ce qui nous retient.

Que de temps investi dans ce "problème simple". Je vais juste laisser ça ici 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: {}; }

Regardez attentivement la dernière ligne.

Avec ces changements, nous aurions pu

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

Quel est le meilleur que nous puissions obtenir si nous utilisons static defaultProps (le vérificateur ts doit être modifié si nous voulons omettre typeof Comp.defaultProps ).
D'autres options, a déjà été dit - HOC, fonte de type.

Voici ma (très moche) tentative basée sur l'idée de 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 , il semble que nous pourrions simplement utiliser cette solution à @types/react , n'est-ce pas ? Je veux dire, si nous remplaçons l'habituel React.ComponentType par votre solution.
Si c'est le cas, peut-être pouvez-vous créer un PR ?

@decademoon votre définition ne gère pas le cas où les accessoires non par défaut incluent en fait des champs facultatifs, c'est-à-dire

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

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

Je l'ai fait fonctionner dans mon cas en changeant votre type RequiredAndPartialDefaultProps pour ne pas envelopper le "RP" avec "Required"

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

Je suis surpris qu'il n'y ait toujours pas de solution appropriée ou au moins un HOC fonctionnel sur le NPM ; à moins que j'ai raté quelque chose.

Salut à tous. Je voulais juste dire et si vous lisez toujours ce fil : je pense que @JoshuaToenyes a fourni l'explication la plus significative et la plus utile. Ce n'est certainement pas un problème donc il n'y a rien à voir avec cela. Utilisez l'assertion de type dans ce cas.

@toiletpatrol en fait, la solution de @decademoon (avec ma légère modification) gère automatiquement les accessoires par défaut très bien. Il pourrait certainement être fusionné dans les définitions DT pour React afin de fournir la norme de fonctionnalité à tout le monde.

@toiletpatrol @RobRendell l'avez-vous vu https://github.com/Microsoft/TypeScript/issues/23812 ?

@vkrol J'ai vu cela, mais je peux abandonner l'implémentation decademoon dans ma base de code dès maintenant sans attendre les versions de nouvelles fonctionnalités.

Une autre solution de contournement que j'utilise pour l'instant pour les cas délicats :

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

Rien de mal à cela, je suppose, donc je le laisse ici comme une solution de contournement sale mais simple.

Les typages TS 3.2 et React 16.7 résolvent ce problème. peut-on fermer ?

@Hotell, comment cela devrait-il être géré finalement ? Je n'arrive toujours pas à le faire fonctionner correctement

Pour faire gagner du temps aux autres, voici un lien vers les notes de version de Typescript 3 :
Prise en charge de defaultProps dans JSX

@cbergmiller Je crains que ce ne soient les notes de publication de TypeScript 3.1 🙃

toujours le même problème avec React.FunctionComponent

@denieler Je ne conseillerais pas d'utiliser defaultProps avec React.FunctionComponent , ce n'est pas naturel. Il est préférable d'utiliser les paramètres de fonction par défaut :

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

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

@mgol Comment définiriez-vous les paramètres de fonction par défaut si je ne voulais pas déstructurer les accessoires ?
Je ne peux penser qu'à déstructurer uniquement les propriétés "par défaut" comme suit :

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>
};

Mais je trouve honteux de n'extraire que certains des accessoires.

@glecetre Vous pouvez utiliser :

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

@Glinkis s'il vous plaît, notez https://github.com/reactjs/rfcs/pull/107/files#diff -20b9b769068a185d90c23b58a2095a9dR184.

@glecetre Pourquoi tu ne veux pas déstructurer tous les accessoires ? C'est plus simple que de définir defaultProps et plus facile à taper. Le type d'accessoires du composant basé sur la classe peut vous mordre si vous exportez pour une utilisation externe, car les accessoires requis peuvent ne plus l'être s'il existe une entrée pour eux dans defaultProps . L'utilisation defaultProps semble également un peu magique alors que dans la déstructuration des paramètres, tout est en JavaScript.

Cette page vous a été utile?
0 / 5 - 0 notes