流程:如何键入接受包装组件不支持的道具的HOC

时间:2017-10-18 20:00:00

标签: reactjs flowtype

我不太确定如何在Flow 0.57.3中输入以下HOC:

// @flow
import React, {Component, type ComponentType} from 'react';

type OwnProps = {
    onFoo: void => void
};

// What we want from the returned wrapper component:
// - enforces presence of `onFoo` prop
// - enforces the prop contract of the passed-in WrappedComponent
function WithOnFoo<Props: {}>(
    WrappedComponent: ComponentType<Props>
): ComponentType<Props & OwnProps> {
    return class WithOnFoo extends Component<Props & OwnProps> {
        componentDidMount() {
            this.props.onFoo();
        }

        render() {
            return <WrappedComponent {...this.props} />;
        }
    };
}

const MyComponent = ({name}: {name: string}) => (
    <p>Hi, {name}</p>
);

const wrapped = WithOnFoo(MyComponent);

尝试here

评论解释了我正在寻找的东西:一个返回的包装器组件

  • 强制执行onFoo prop
  • 强制执行传入的WrappedComponent
  • 的prop契约

Flow抱怨说:

20:             return <WrappedComponent {...this.props} />;
                       ^ props of React element `WrappedComponent`. This type is incompatible with
11: function WithOnFoo<Props: {}>(    ^ some incompatible instantiation of `Props`

我不太确定这个错误在抱怨什么。我知道我没有痛苦将HOC的onFoo道具传递给WrappedComponent,但我不确定是不是问题的根源。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

虽然<Props: {}>允许传播this.props,但我们知道onFoo应该是要包装的组件的道具的一部分。所以我们应该声明传递给WithOnFoo的组件的道具有onFoo,即

function withOnFoo<Props: {} & OwnProps>(
    WrappedComponent: ComponentType<Props>
): ComponentType<Props> {
    // implementation here ...
}

另请注意Props是&#34;头等&#34;在WithOnFoo(将具有onFoo)的实现细节中键入。因此,您可以将Props & OwnProps替换为Props

请参阅the flow example here

注意:我修改了一些术语以帮助自己理解您的示例

WithOnFoo变为callsOnFooOnComponentDidMount

OwnProps变为RequiredProps

答案 1 :(得分:1)

在渲染包装组件时尝试从道具列表中删除onFoo。似乎让错误消失了。

render() {
  const {onFoo, ...props} = this.props;
  return <WrappedComponent {...props} />;
}

请参阅example