繁体   English   中英

如何使用函数构造函数将类组件转换为函数式?

[英]How convert class component to functional with function constructor?

我正在尝试将此类组件转换为函数组件,但我需要该组件具有这些静态属性。

export class InputBox<T extends string|number|undefined = undefined> extends React.Component<IInputBoxProps<T>, IInputBoxState> {
    static displayName = "InputBox";
    static defaultProps: IInputBoxProps<string|number> = {
        disabled: false,
        rightAligned: false,
        id: "",
        keySelectIndex: 0,
    }

... rest of component
}

我试过这个代码:

export const InputBox: React.FunctionComponent<IInputBoxProps<any>> = <T extends string | number | undefined = undefined >(props: IInputBoxProps<T>) => {
    InputBox.displayName = "InputBox";
    InputBox.defaultProps = {
        disabled: false,
        rightAligned: false,
        id: "",
        keySelectIndex: 0,
    }

... rest of component
}

当我运行此代码时,我收到一个 eslint 错误,指出:

FunctionComponent<IInputBox<any>>' is not a constructor function type.

T = any在这里也不起作用。 我知道any都会使打字稿无用,但我似乎无法解决这个错误。

如何使用“构造函数类型”键入函数组件,这究竟是什么意思?

类构造函数中的函数构造函数和类构造函数有什么区别? 我应该在函数组件中以不同的方式键入静态道具吗?

通用组件

export const InputBox: React.FunctionComponent<IInputBoxProps<any>> = <T ...

这种语法永远不会正常工作,因为您试图在函数本身上设置泛型T 泛型的要点是每次调用函数时T都可能不同。

所以你不能在这里使用React.FunctionComponent类型。 但是你不需要——只需设置道具的类型。

如果您的 eslint 设置使用规则explicit-module-boundary-names那么您还需要将返回类型设置为JSX.Element (或JSX.Element | null如果它可能返回null )。


默认道具

defaultProps在函数组件上并不真正存在(请参阅此处的讨论)。 与其尝试在函数组件上设置defaultProps属性,不如考虑该属性实际在做什么以及如何实现该功能。

我会通过使用defaultProps中的值作为解构属性时的默认值来处理这个问题。 (注意:我不确定这里的T适用于什么)。

const InputBox = <T extends string | number | undefined = undefined>(
    props: IInputBoxProps<T>
) => {
    const {
        disabled = false,
        rightAligned = false,
        id = "",
        keySelectIndex = 0,
        // ... other props without defaults
    } = props;
...

或内联

const InputBox = <T extends string | number | undefined = undefined>(
    { disabled = false, rightAligned = false, id = "", keySelectIndex = 0, data }: IInputBoxProps<T>
) => {
...

显示名称

displayName并不是真正需要的,因为推断的显示名称将是函数的名称。 它已经是"InputBox" 如果您使用了选项{ ignoreTranspilerName: true }那么您应该只会在此处收到 eslint 错误。

正如您在规则示例中看到的,您必须首先创建函数,然后将displayName属性分配给函数。 Aleksey 的评论正确地做到了这一点。

const InputBox = <T extends string | number | undefined = undefined>(
    props: IInputBoxProps<T>
): JSX.Element => {
    /* ... */
}
InputBox.displayName = "InputBox";

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM