Реагировать с помощью TypeScript - определять defaultProps в функции без сохранения
Я использую React с TypeScript, и я создал функцию без состояния. Я удалил ненужный код из примера для удобочитаемости.
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>;
};
Все отлично, и этот код работает правильно. Но вот мой вопрос: как я могу определить defaultProps
для компонента CenterBox
?
Как упоминается в реагировать на документы:
(...) Они являются чистыми функциональными преобразованиями их ввода, с нулевым шаблонный. Тем не менее, вы все равно можете указать .propTypes и .defaultProps, установив их как свойства функции, так же, как вы должны установить их в классе ES6. (...)
это должно быть легко:
CenterBox.defaultProps = {
minHeight: 250
}
Но этот код генерирует ошибку TSLint: error TS2339: Property 'defaultProps' does not exist on type '(props: CenterBoxProps) => Element'.
Итак, как я могу правильно определить defaultProps
в моем выше стеке (React + TypeScript)?
Ответы
Ответ 1
Через 2 часа поиска решения... работает.
Если вы хотите определить deufaultProps
, ваша строка, определяющая вашу функцию, должна выглядеть так:
export const CenterBox: React.SFC<CenterBoxProps> = props => {
(...)
};
Затем вы можете определить реквизиты, например:
CenterBox.defaultProps = { someProp: true }
Обратите внимание, что React.SFC
является псевдонимом для React.StatelessComponent
.
Я надеюсь, что этот вопрос (и ответ) поможет кому-то. Убедитесь, что вы установили новейшие титры React.
Ответ 2
И здесь, как это работает для функций с сохранением состояния, если другие наткнуться на это.
Ключ объявляет defaultProps как статическую переменную.
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;
};
Ответ 3
Я считаю, что лучший способ, чем описанный в документации по React, - это просто использовать аргументы Javascript/Typescript по умолчанию.
Здесь ответ здесь: fooobar.com/questions/1654464/... но для удобства приведу пример:
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;
Это позволит Typescript знать, что вам не нужно предоставлять реквизит, а также что он никогда не будет "неопределенным" внутри вашего компонента.
Ответ 4
Для функциональных компонентов, начиная с React 16.7.0, тип 'React.SFC' не рекомендуется в пользу ' React.FC
'.
пример
type TFuncComp = React.FC<{ text: string }>
const FuncComp: TFuncComp = props => <strong>{props.text}</strong>
FuncComp.defaultProps = { text: 'Empty Text' }
Предупреждение об устаревании в источнике
Тип FC (FunctionalComponent) в источнике
Ответ 5
Ввод реквизитов по умолчанию в компонент функции с помощью React.FC может привести к ошибке ложного типа:
type Props = {
required: string,
} & typeof defaultProps;
const defaultProps = {
optDefault: 'optDefault'
};
const MyComponent: React.FC<Props> = (props: Props) => (
<ul>
<li>required: {props.required}</li>
<li>optDefault: {props.optDefault}</li>
</ul>
)
MyComponent.defaultProps = defaultProps;
ReactDOM.render(
<div>
<MyComponent
required='required'
optDefault='over written'
/>
<MyComponent /* type error <---- false type error */
required='required'
/>
</div>,
document.getElementById('app')
);
ошибка:
[tsserver 2741] Property 'optDefault' is missing in type '{ required: string; }' but required in type '{ optDefault: string; }'. [E]
Другим предлагаемым решением является использование собственных параметров функции Javascript по умолчанию:
type Props = {
required: string,
optDefault?: string
}
const MyComponent: React.FC<Props> = ({
required,
optDefault='default'
}: Props) => (
<ul>
<li>required: {required}</li>
<li>optDefault: {optDefault}</li>
</ul>
)
ReactDOM.render(
<div>
<MyComponent
required='required'
optDefault='over written'
/>
<MyComponent
required='required'
/>
</div>,
document.getElementById('app')
);
Но проблема с этим решением заключается в том, что если вы забыли указать значение по умолчанию, это приведет к ошибке времени выполнения:
const MyComponent: React.FC<Props> = ({
required,
optDefault //='optDefault' //<--- if you forgot to provide default
}: Props) => (
<ul>
<li>required: {required}</li>
<li>optDefault: {optDefault}</li> {/* <-- result in bug */}
</ul>
)
Лучшее решение - вообще не использовать React.FC, просто полагаться на вывод типа Typescript:
type Props = {
required: string,
} & typeof defaultProps;
const defaultProps = {
optDefault: 'optDefault'
};
const MyComponent = (props: Props) => (
<ul>
<li>required: {props.required}</li>
<li>optDefault: {props.optDefault}</li>
</ul>
)
MyComponent.defaultProps = defaultProps
ReactDOM.render(
<div>
<MyComponent
required='required'
optDefault='over written'
/>
<MyComponent
required='required'
/>
</div>,
document.getElementById('app')
);
Ответ 6
Вы можете поместить это в свой компонент
static defaultProps: any;