我正在使用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
?
正如react docs中提到的那样:
(...)它们是输入的纯函数变换,为零 样板。但是,您仍可以指定.propTypes和 .defaultProps 将它们设置为函数的属性,就像 你可以在ES6课上设置它们。 (...)
应该很容易:
CenterBox.defaultProps = {
minHeight: 250
}
但是此代码生成TSLint错误:error TS2339: Property 'defaultProps' does not exist on type '(props: CenterBoxProps) => Element'.
再次说明:如何在上面的堆栈中正确定义defaultProps
(React + TypeScript)?
答案 0 :(得分:21)
寻找解决方案2小时后...... 它的工作。
如果要定义deufaultProps
,则函数定义行应如下所示:
export const CenterBox: React.SFC<CenterBoxProps> = props => {
(...)
};
然后你可以定义像:
这样的道具CenterBox.defaultProps = { someProp: true }
请注意,React.SFC
是React.StatelessComponent
的别名。
我希望这个问题(和答案)可以帮助别人。确保您已安装最新的React类型。
答案 1 :(得分:8)
以下是有状态函数的工作原理,以防其他人偶然发现这种情况。 关键是将 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;
};
答案 2 :(得分:2)
我相信比React文档中描述的更好的方法是简单地使用Javascript / Typescript默认参数。
这里有一个答案:https://stackoverflow.com/a/54569933/484190,但是为了方便起见,下面是一个示例:
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知道您不必提供道具,并且永远不会在组件内部对其进行“不确定”
答案 3 :(得分:1)
对于自 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' }
答案 4 :(得分:1)
使用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')
);
答案 5 :(得分:0)
您可以将其放入组件中
static defaultProps: any;
答案 6 :(得分:-1)
对我来说,最简单的方法是直接在defaultProps中定义(部分)默认值:
export default class TSError extends React.Component<ITSErrorProps, {}> {
private static defaultProps: Partial<ITSErrorProps> = {
fullPage: true,
controlClick: true,
doubleClick: true
};
...
}