Domyślne rekwizyty z komponentem klasy
Używanie static defaultProps
jest poprawne. Powinieneś także używać interfejsów, a nie klas, dla właściwości i stanu.
Aktualizacja 2018/12/1 : TypeScript poprawił sprawdzanie typów związane z defaultProps
upływem czasu. Czytaj dalej, aby poznać najnowsze i najlepsze zastosowania, aż do starszych zastosowań i problemów.
W przypadku języka TypeScript 3.0 i nowszych
Specjalnie dodano obsługędefaultProps
języka TypeScript, aby sprawdzanie typów działało zgodnie z oczekiwaniami. Przykład:
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>
);
}
}
Które można renderować i kompilować bez przekazywania foo
atrybutu:
<PageComponent bar={ "hello" } />
Zauważ, że:
foo
nie jest oznaczony jako opcjonalny (tj. foo?: string
), mimo że nie jest wymagany jako atrybut JSX. Oznaczenie jako opcjonalne oznaczałoby, że tak może być undefined
, ale w rzeczywistości nigdy tak nie będzie, undefined
ponieważ defaultProps
zapewnia wartość domyślną. Pomyśl o tym podobnie do tego , jak możesz oznaczyć parametr funkcji jako opcjonalny lub jako wartość domyślną, ale nie obie, ale oba oznaczają, że wywołanie nie musi określać wartości . TypeScript 3.0+ traktuje defaultProps
w podobny sposób, co jest naprawdę fajne dla użytkowników Reacta!
- Nie
defaultProps
ma wyraźnej adnotacji typu. Jego typ jest wywnioskowany i używany przez kompilator do określenia, które atrybuty JSX są wymagane. Możesz użyć, defaultProps: Pick<PageProps, "foo">
aby zapewnić defaultProps
dopasowanie podzbioru PageProps
. Więcej informacji na temat tego zastrzeżenia wyjaśniono tutaj .
- Wymaga to
@types/react
wersji 16.4.11
do prawidłowego działania.
Dla TypeScript 2.1 do 3.0
Przed zaimplementowaniem obsługi kompilatora TypeScript 3.0 defaultProps
nadal można było z niego korzystać i działało w 100% z React w czasie wykonywania, ale ponieważ TypeScript uwzględniał właściwości tylko podczas sprawdzania atrybutów JSX, musiałbyś oznaczyć właściwości, które mają wartości domyślne, jako opcjonalne ?
. Przykład:
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>
);
}
}
Zauważ, że:
- To dobry pomysł, aby annotate
defaultProps
z Partial<>
tak, że typu kontrole przeciw rekwizytów, ale nie trzeba dostarczyć wszelkich wymaganych własności o wartości domyślnej, która nie ma sensu, ponieważ wymagane właściwości nie powinny potrzebować domyślną.
- Podczas korzystania
strictNullChecks
z wartości this.props.foo
będzie possibly undefined
i wymagać potwierdzenia niezerowego (tj. this.props.foo!
) Lub zabezpieczenia typu (tj. if (this.props.foo) ...
) Do usunięcia undefined
. Jest to denerwujące, ponieważ domyślna wartość właściwości oznacza, że w rzeczywistości nigdy nie będzie ona niezdefiniowana, ale TS nie zrozumiał tego przepływu. To jeden z głównych powodów, dla których TS 3.0 dodał wyraźne wsparcie dla defaultProps
.
Przed TypeScript 2.1
Działa to tak samo, ale nie masz Partial
typów, więc po prostu pomiń Partial<>
i albo podaj domyślne wartości dla wszystkich wymaganych właściwości (nawet jeśli te domyślne nigdy nie będą używane) lub całkowicie pomiń jawną adnotację typu.
Możesz również użyć defaultProps
na składnikach funkcji, ale musisz wpisać swoją funkcję w interfejsie FunctionComponent
( StatelessComponent
w @types/react
poprzedniej wersji 16.7.2
), aby TypeScript wiedział o defaultProps
funkcji:
interface PageProps {
foo?: string;
bar: number;
}
const PageComponent: FunctionComponent<PageProps> = (props) => {
return (
<span>Hello, {props.foo}, {props.bar}</span>
);
};
PageComponent.defaultProps = {
foo: "default"
};
Zauważ, że nie musisz Partial<PageProps>
nigdzie używać, ponieważ FunctionComponent.defaultProps
jest już określony jako częściowy w TS 2.1+.
Inną fajną alternatywą (właśnie tego używam) jest zniszczenie props
parametrów i bezpośrednie przypisanie wartości domyślnych:
const PageComponent: FunctionComponent<PageProps> = ({foo = "default", bar}) => {
return (
<span>Hello, {foo}, {bar}</span>
);
};
Wtedy wcale nie potrzebujesz defaultProps
! Należy pamiętać, że jeśli nie dostarczają defaultProps
na składnik funkcji będzie mieć pierwszeństwo przed wartościami parametrów domyślnych, bo React zawsze wyraźnie przekazać defaultProps
wartości (tak parametry nie są niezdefiniowane, więc parametr domyślny jest nie używany). Tak byłoby użyć jeden lub drugi, nie oba.
static defaultProps
jest poprawne. Czy możesz wysłać ten kod?