Свойства по умолчанию с компонентом класса
Использование static defaultPropsправильно. Вы также должны использовать интерфейсы, а не классы, для свойств и состояния.
Обновление 2018/12/1 : TypeScript defaultPropsсо временем улучшил проверку типов . Читайте, чтобы узнать о последних и наиболее эффективных способах использования, вплоть до более старых способов использования и проблем.
Для TypeScript 3.0 и выше
TypeScript специально добавил поддержку,defaultProps чтобы проверка типов работала так, как вы ожидаете. Пример:
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>
);
}
}
Что можно отобразить и скомпилировать без передачи fooатрибута:
<PageComponent bar={ "hello" } />
Обратите внимание, что:
fooэто не отмечен факультативным (то есть foo?: string) , даже если это не требуется в качестве атрибута JSX. Пометка как необязательная будет означать, что это может быть undefined, но на самом деле этого никогда не будет, undefinedпотому что defaultPropsпредоставляется значение по умолчанию. Думайте об этом аналогично тому, как вы можете пометить параметр функции как необязательный или со значением по умолчанию, но не обоими сразу, но оба они означают, что при вызове не нужно указывать значение . TypeScript 3.0+ defaultPropsработает аналогично, что действительно здорово для пользователей React!
- Не
defaultPropsимеет явной аннотации типа. Его тип определяется и используется компилятором, чтобы определить, какие атрибуты JSX требуются. Вы можете использовать defaultProps: Pick<PageProps, "foo">для обеспечения defaultPropsсовпадений подмножество PageProps. Подробнее об этом предупреждении рассказывается здесь .
- Для правильной работы требуется
@types/reactверсия 16.4.11.
Для TypeScript с 2.1 по 3.0
До того, как TypeScript 3.0 реализовал поддержку компилятора, defaultPropsвы все еще могли его использовать, и он работал на 100% с React во время выполнения, но поскольку TypeScript учитывал только реквизиты при проверке атрибутов JSX, вам нужно было бы пометить реквизиты, которые имеют значения по умолчанию, как необязательные ?. Пример:
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>
);
}
}
Обратите внимание, что:
- Это хорошая идея , чтобы аннотировать
defaultPropsс Partial<>так , что его типом проверок в отношении вашего реквизита, но вы не должны предоставлять все требуемое свойство со значением по умолчанию, что не имеет смысла , так как требуемые свойства никогда не должны по умолчанию.
- При использовании
strictNullChecksзначения this.props.foowill будет possibly undefinedи потребуется удаление ненулевого утверждения (т.е. this.props.foo!) или защиты типа (т.е. if (this.props.foo) ...) undefined. Это раздражает, поскольку значение свойства по умолчанию означает, что оно никогда не будет неопределенным, но TS не понимает этот поток. Это одна из основных причин, по которой в TS 3.0 была добавлена явная поддержка defaultProps.
До TypeScript 2.1
Это работает так же, но у вас нет Partialтипов, поэтому просто опустите Partial<>и либо укажите значения по умолчанию для всех необходимых реквизитов (даже если эти значения по умолчанию никогда не будут использоваться), либо полностью опустите явную аннотацию типа.
Вы также можете использовать defaultPropsкомпоненты функций, но вы должны ввести свою функцию в интерфейс FunctionComponent( StatelessComponentв более @types/reactранней версии 16.7.2), чтобы TypeScript знал о defaultPropsфункции:
interface PageProps {
foo?: string;
bar: number;
}
const PageComponent: FunctionComponent<PageProps> = (props) => {
return (
<span>Hello, {props.foo}, {props.bar}</span>
);
};
PageComponent.defaultProps = {
foo: "default"
};
Обратите внимание, что вам не нужно Partial<PageProps>нигде использовать, потому что FunctionComponent.defaultPropsэто уже указано как частичное в TS 2.1+.
Еще одна хорошая альтернатива (это то, что я использую) - это деструктурировать ваши propsпараметры и напрямую присвоить значения по умолчанию:
const PageComponent: FunctionComponent<PageProps> = ({foo = "default", bar}) => {
return (
<span>Hello, {foo}, {bar}</span>
);
};
Тогда вам это вообще не нужно defaultProps! Имейте в виду , что если вы действительно обеспечивают defaultPropsна функции компонента будет иметь приоритет над значениями параметров по умолчанию, потому что React будет всегда явно передать defaultPropsзначения (поэтому параметры никогда не определено, что параметр по умолчанию никогда не используется.) Таким образом , вы будете использовать один или другой, но не оба.
static defaultPropsправильно. Вы можете опубликовать этот код?