Domyślne rekwizyty z komponentem klasy
Używanie static defaultPropsjest 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 defaultPropsupł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 fooatrybutu:
<PageComponent bar={ "hello" } />
Zauważ, że:
foonie 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, undefinedponieważ defaultPropszapewnia 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 defaultPropsw podobny sposób, co jest naprawdę fajne dla użytkowników Reacta!
- Nie
defaultPropsma 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ć defaultPropsdopasowanie podzbioru PageProps. Więcej informacji na temat tego zastrzeżenia wyjaśniono tutaj .
- Wymaga to
@types/reactwersji 16.4.11do prawidłowego działania.
Dla TypeScript 2.1 do 3.0
Przed zaimplementowaniem obsługi kompilatora TypeScript 3.0 defaultPropsnadal 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
defaultPropsz 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
strictNullChecksz wartości this.props.foobędzie possibly undefinedi 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 Partialtypó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ć defaultPropsna składnikach funkcji, ale musisz wpisać swoją funkcję w interfejsie FunctionComponent( StatelessComponentw @types/reactpoprzedniej wersji 16.7.2), aby TypeScript wiedział o defaultPropsfunkcji:
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.defaultPropsjest już określony jako częściowy w TS 2.1+.
Inną fajną alternatywą (właśnie tego używam) jest zniszczenie propsparametró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ą defaultPropsna składnik funkcji będzie mieć pierwszeństwo przed wartościami parametrów domyślnych, bo React zawsze wyraźnie przekazać defaultPropswartoś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 defaultPropsjest poprawne. Czy możesz wysłać ten kod?