web-dev-qa-db-fra.com

Réagissez avec TypeScript - définissez defaultProps dans une fonction sans état

J'utilise React avec TypeScript et j'ai créé une fonction sans état. J'ai supprimé le code inutile de l'exemple pour plus de lisibilité.

interface CenterBoxProps extends React.Props<CenterBoxProps> {
    minHeight?: number;
}

export const CenterBox = (props: CenterBoxProps) => {
    const minHeight = props.minHeight || 250;
    const style = {
        minHeight: minHeight
    };
    return <div style={style}>Example div</div>;
};

Tout est génial et ce code fonctionne correctement. Mais ma question est la suivante: comment définir defaultProps pour le composant CenterBox?

Comme mentionné dans react docs :

(...) Ce sont des transformations fonctionnelles pures de leur entrée, avec zéro Passe-partout. Toutefois, vous pouvez toujours spécifier .propTypes et .defaultProps en les définissant comme propriétés de la fonction, tout comme vous les définiriez dans une classe ES6. (...)

cela devrait être facile comme:

CenterBox.defaultProps = {
    minHeight: 250
}

Mais ce code génère une erreur TSLint: error TS2339: Property 'defaultProps' does not exist on type '(props: CenterBoxProps) => Element'.

Encore une fois: comment définir correctement la variable defaultProps dans la pile ci-dessus (React + TypeScript)?

16

Après 2 heures de recherche de solution ... ça marche .

Si vous voulez définir deufaultProps votre ligne de définition de fonction devrait ressembler à ceci:

export const CenterBox: React.SFC<CenterBoxProps> = props => {
    (...)
};

Ensuite, vous pouvez définir des accessoires comme:

CenterBox.defaultProps = { someProp: true }

Notez que React.SFC est un alias pour React.StatelessComponent.

J'espère que cette question (et sa réponse) aidera quelqu'un. Assurez-vous d'avoir installé les derniers typages React.

20

Et voici comment cela fonctionne pour les fonctions avec état au cas où d’autres tomberaient sur cela. La clé déclare/ defaultProps en tant que variable statique.

interface IBoxProps extends React.Props<IBoxProps> {
    x?: number;
    y?: number;
    height?: number;
    width?: number;
}

interface IBoxState {
    visible?: boolean;
}

export default class DrawBox extends React.Component<IBoxProps, IBoxState> {
    static defaultProps: IBoxProps;

    constructor(props: IBoxProps) {
        super(props);
    }
    ...
}

DrawBox.defaultProps = {
    x=0;
    y=0;
    height=10;
    weight=10;
};
7
Mark Peterson

Pour Composants fonctionnels à partir de React 16.7.0 le type 'React.SFC' est obsolète en faveur de 'React.FC'.

Exemple

type TFuncComp = React.FC<{ text: string }>

const FuncComp: TFuncComp = props => <strong>{props.text}</strong>

FuncComp.defaultProps = { text: 'Empty Text' }

Avertissement de dépréciation de la source

Type FC (FunctionalComponent) dans la source

1
robstarbuck

Je crois qu'une meilleure façon que celle décrite dans la documentation de React consiste simplement à utiliser les arguments par défaut Javascript/TypeScript.

Il y a une réponse ici: https://stackoverflow.com/a/54569933/484190 mais par commodité, voici un exemple:

import React, { FC } from "react";

interface CompProps {
  x?: number;
  y?: number;
}

const Comp: FC<CompProps> = ({ x = 10, y = 20 }) => {
  return <div>{x}, {y}</div>;
}

export default Comp;

Cela permettra à TypeScript de savoir que vous n'avez pas à fournir l'accessoire, et qu'il ne sera jamais "indéfini" dans votre composant

0
pete otaqui