使用 Typescript 的 React 组件中的默认函数值

IT技术 reactjs typescript asp.net-core
2021-05-09 14:39:26

问题与非常相似,但我的重点是默认功能。(我是前端新手,如果有更正式的名称,请告诉我)

这是代码(我使用的是 TypeScript 2.5):

export const TestProps = {
    Hello: (name: string) => {
        console.log(name);
    }
}

type TestPropsType = typeof TestProps;

export class TestComp extends React.Component<TestPropsType, {}>{    
    public render() {
        this.props.Hello("world");
        return <div>test</div>;
    }
}

然后,当我尝试渲染此组件时:

ReactDOM.render(<TestComp />, document.getElementById("page"));

我收到这个错误;

TS2322:类型“{}”不可分配给类型“IntrinsicAttributes & IntrinsicClassAttributes & Readonly<{ children?: ReactNode; }> & ...'。类型 '{}' 不能分配给类型 'Readonly<{ Hello: (name: string) => void; }>'。

类型“{}”中缺少属性“Hello”。

我该如何解决这个问题?

1个回答

首先,让我们修复您的示例:

interface TestProps {
    Hello?: { (name: string): void };
}

export class TestComp extends React.Component<TestProps, {}> {    
    public static defaultProps: Partial<TestProps> = {
        Hello: name => console.log(name)
    };

    public render() {
        this.props.Hello("world");
        return <div>test</div>;
    }
}

您之前编写它的方式意味着您的组件无法看到TestProps(它不是从任何地方传入的),这Hello是必需的props。我使用了一个接口Hello?使其成为可选的,而不是使用typeof.

编译器错误来自Hello所需的事实,因此您需要使用:

ReactDOM.render(<TestComp Hello={() => {}} />, document.getElementById("page"));
                       // ^ pass Hello as a prop here

这样做会修复编译错误,但您仍然会留下不正确的行为,因为TestProps您的示例中的对象永远不会被使用。

如果您正在使用strictNullChecks,那么您将不得不稍微处理一下类型系统,因为它Hello是一个可选属性:

if (this.props.Hello) this.props.Hello("world");
// or
this.props.Hello && this.props.Hello("world");

通过检查是否this.props.Hellotruthy,类型从缩小(name: string) => void | undefined到 just (name: string) => void,这样就可以调用函数了。