Accessoires par défaut avec composant de classe
L'utilisation static defaultProps
est correcte. Vous devriez également utiliser des interfaces, pas des classes, pour les accessoires et l'état.
Mise à jour 2018/12/1 : TypeScript a amélioré la vérification de type liée au defaultProps
fil du temps. Poursuivez votre lecture pour connaître les utilisations les plus récentes et les plus importantes jusqu'aux utilisations et problèmes plus anciens.
Pour TypeScript 3.0 et plus
TypeScript a spécifiquement ajouté la prise en charge pourdefaultProps
que la vérification de type fonctionne comme vous le souhaitez. Exemple:
interface PageProps {
foo: string;
bar: string;
}
export class PageComponent extends React.Component<PageProps, {}> {
public static defaultProps = {
foo: "default"
};
public render(): JSX.Element {
return (
<span>Hello, { this.props.foo.toUpperCase() }</span>
);
}
}
Qui peut être rendu et compilé sans passer d' foo
attribut:
<PageComponent bar={ "hello" } />
Notez que:
foo
n'est pas marqué comme facultatif (c'est-à-dire foo?: string
) même s'il n'est pas requis comme attribut JSX. Marquer comme facultatif signifierait que cela pourrait l'être undefined
, mais en fait, ce ne sera jamais undefined
parce que defaultProps
fournit une valeur par défaut. Pensez-y de la même manière que vous pouvez marquer un paramètre de fonction comme facultatif, ou avec une valeur par défaut, mais pas les deux, mais les deux signifient que l'appel n'a pas besoin de spécifier une valeur . TypeScript 3.0+ traite defaultProps
de la même manière, ce qui est vraiment cool pour les utilisateurs de React!
- Le
defaultProps
n'a pas d'annotation de type explicite. Son type est déduit et utilisé par le compilateur pour déterminer les attributs JSX requis. Vous pouvez utiliser defaultProps: Pick<PageProps, "foo">
pour vous assurer que defaultProps
correspond à un sous-ensemble de PageProps
. Plus d'informations sur cette mise en garde sont expliquées ici .
- Cela nécessite une
@types/react
version 16.4.11
pour fonctionner correctement.
Pour TypeScript 2.1 jusqu'à 3.0
Avant que TypeScript 3.0 n'implémente la prise en charge du compilateur, defaultProps
vous pouviez toujours l'utiliser, et cela fonctionnait à 100% avec React au moment de l'exécution, mais comme TypeScript ne considérait que les accessoires lors de la vérification des attributs JSX, vous deviez marquer les accessoires qui ont des valeurs par défaut comme facultatifs avec ?
. Exemple:
interface PageProps {
foo?: string;
bar: number;
}
export class PageComponent extends React.Component<PageProps, {}> {
public static defaultProps: Partial<PageProps> = {
foo: "default"
};
public render(): JSX.Element {
return (
<span>Hello, world</span>
);
}
}
Notez que:
- C'est une bonne idée d'annoter
defaultProps
avec Partial<>
pour qu'il vérifie le type par rapport à vos accessoires, mais vous n'avez pas à fournir à chaque propriété requise une valeur par défaut, ce qui n'a aucun sens puisque les propriétés requises ne devraient jamais avoir besoin d'une valeur par défaut.
- Lorsque vous utilisez
strictNullChecks
la valeur de this.props.foo
sera possibly undefined
et nécessitera une assertion non nulle (ie this.props.foo!
) ou un type-guard (ie if (this.props.foo) ...
) pour supprimer undefined
. C'est ennuyeux car la valeur de prop par défaut signifie qu'il ne sera jamais indéfini, mais TS n'a pas compris ce flux. C'est l'une des principales raisons pour lesquelles TS 3.0 a ajouté un support explicite pour defaultProps
.
Avant TypeScript 2.1
Cela fonctionne de la même manière mais vous n'avez pas de Partial
types, alors omettez simplement Partial<>
et fournissez les valeurs par défaut pour tous les accessoires requis (même si ces valeurs par défaut ne seront jamais utilisées) ou omettez complètement l'annotation de type explicite.
Vous pouvez également utiliser defaultProps
des composants de fonction, mais vous devez taper votre fonction dans l' interface FunctionComponent
( StatelessComponent
dans la @types/react
version antérieure 16.7.2
) afin que TypeScript sache defaultProps
sur la fonction:
interface PageProps {
foo?: string;
bar: number;
}
const PageComponent: FunctionComponent<PageProps> = (props) => {
return (
<span>Hello, {props.foo}, {props.bar}</span>
);
};
PageComponent.defaultProps = {
foo: "default"
};
Notez que vous ne devez utiliser Partial<PageProps>
nulle part car il FunctionComponent.defaultProps
est déjà spécifié comme partiel dans TS 2.1+.
Une autre alternative intéressante (c'est ce que j'utilise) est de déstructurer vos props
paramètres et d'attribuer directement les valeurs par défaut:
const PageComponent: FunctionComponent<PageProps> = ({foo = "default", bar}) => {
return (
<span>Hello, {foo}, {bar}</span>
);
};
Alors vous n'en avez pas du tout besoin defaultProps
! Sachez que si vous ne fournissez defaultProps
sur un composant de fonction , il aura la priorité sur les valeurs des paramètres par défaut, car React toujours passer explicitement les defaultProps
valeurs (si les paramètres ne sont jamais non défini, donc le paramètre par défaut est jamais utilisé.) Vous utiliseriez l'un ou l'autre, pas les deux.
static defaultProps
est correct. Pouvez-vous publier ce code?