Puntelli predefiniti con componente di classe
L'uso static defaultProps
è corretto. Dovresti anche usare interfacce, non classi, per oggetti di scena e stato.
Aggiornamento 2018/12/1 : TypeScript ha migliorato il controllo del tipo relativo al defaultProps
tempo. Continua a leggere per l'utilizzo più recente e più efficace, fino agli usi e ai problemi precedenti.
Per TypeScript 3.0 e versioni successive
TypeScript ha aggiuntodefaultProps
specificamente il supporto per far funzionare il controllo del tipo come ti aspetteresti. Esempio:
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>
);
}
}
Che può essere reso e compilato senza passare un foo
attributo:
<PageComponent bar={ "hello" } />
Nota che:
foo
non è contrassegnato come facoltativo (ovvero foo?: string
) anche se non è richiesto come attributo JSX. Contrassegnare come facoltativo significherebbe che potrebbe esserlo undefined
, ma in realtà non lo sarà mai undefined
perché defaultProps
fornisce un valore predefinito. Pensalo in modo simile a come puoi contrassegnare un parametro di funzione facoltativo o con un valore predefinito, ma non entrambi, ma entrambi significano che la chiamata non deve specificare un valore . TypeScript 3.0+ tratta defaultProps
in modo simile, il che è davvero interessante per gli utenti di React!
- Non
defaultProps
ha annotazioni di tipo esplicite. Il suo tipo viene dedotto e utilizzato dal compilatore per determinare quali attributi JSX sono richiesti. È possibile utilizzare defaultProps: Pick<PageProps, "foo">
per garantire defaultProps
corrispondenze a un sottoinsieme di PageProps
. Maggiori informazioni su questo avvertimento sono spiegate qui .
- Ciò richiede che la
@types/react
versione 16.4.11
funzioni correttamente.
Per TypeScript 2.1 fino alla 3.0
Prima che TypeScript 3.0 implementasse il supporto del compilatore per defaultProps
te, potresti comunque utilizzarlo, e funzionava al 100% con React in fase di runtime, ma poiché TypeScript considerava solo gli oggetti di scena quando controllava gli attributi JSX, dovresti contrassegnare gli oggetti con valori predefiniti come facoltativi ?
. Esempio:
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>
);
}
}
Nota che:
- E 'una buona idea di annotare
defaultProps
con Partial<>
in modo che tipo di controlli contro i vostri oggetti di scena, ma non c'è bisogno di fornire ogni proprietà richiesta con un valore di default, che non ha senso dal momento che le proprietà richieste non dovrebbero mai bisogno di un default.
- Quando si utilizza
strictNullChecks
il valore di this.props.foo
sarà possibly undefined
e richiederà un'asserzione non nulla (ie this.props.foo!
) o type-guard (ie if (this.props.foo) ...
) da rimuovere undefined
. Questo è fastidioso poiché il valore di prop predefinito significa che in realtà non sarà mai indefinito, ma TS non ha capito questo flusso. Questo è uno dei motivi principali per cui TS 3.0 ha aggiunto il supporto esplicito defaultProps
.
Prima di TypeScript 2.1
Funziona allo stesso modo ma non hai Partial
tipi, quindi ometti Partial<>
e fornisci i valori predefiniti per tutti gli oggetti di scena richiesti (anche se quei valori predefiniti non verranno mai utilizzati) o ometti completamente l'annotazione di tipo esplicito.
Puoi utilizzare anche i defaultProps
componenti delle funzioni, ma devi digitare la tua funzione nell'interfaccia FunctionComponent
( StatelessComponent
nella @types/react
versione precedente 16.7.2
) in modo che TypeScript sia a conoscenza defaultProps
della funzione:
interface PageProps {
foo?: string;
bar: number;
}
const PageComponent: FunctionComponent<PageProps> = (props) => {
return (
<span>Hello, {props.foo}, {props.bar}</span>
);
};
PageComponent.defaultProps = {
foo: "default"
};
Si noti che non è necessario utilizzare da Partial<PageProps>
nessuna parte perché FunctionComponent.defaultProps
è già specificato come parziale in TS 2.1+.
Un'altra bella alternativa (questo è quello che uso) è quella di destrutturare i props
parametri e assegnare direttamente i valori predefiniti:
const PageComponent: FunctionComponent<PageProps> = ({foo = "default", bar}) => {
return (
<span>Hello, {foo}, {bar}</span>
);
};
Quindi non ti serve defaultProps
affatto! Essere consapevoli del fatto che se non fornisci defaultProps
su un componente funzione che avrà la precedenza sui valori di default dei parametri, perché Reagire sarà sempre passare esplicitamente i defaultProps
valori (in modo che i parametri non sono mai definito, quindi il parametro di default non viene mai usato.) Allora devi usare l'uno o l'altro, non entrambi.
static defaultProps
è corretto. Puoi pubblicare quel codice?