Flow(0.58+)如何使用withRouter包装组件时定义子道具

时间:2017-11-04 05:34:29

标签: reactjs react-router flowtype

使用Flow 0.58 +,React和react-router-dom,定义包含withRouter的组件的道具子项的正确方法是什么?

目前,在尝试指定使用withRouter包装的组件的子类型时,我有一种奇怪的行为。

我们假设一个RouterAware组件:

import React, { type Node } from 'react';
import { withRouter } from 'react-router-dom';

type Props = {
  children: Node
};

const RouterAware = (props: Props) => <div>{props.children}</div>;

export default withRouter(RouterAware);

然后使用这个组件:

const Root = () => (
  <RouterAware>
    <div>One</div>
    <div>Two</div>
  </RouterAware>
);

但是,这会产生8个Flow错误,为React.Node定义的8种联合类型中的每一种都有一个错误:

declare type React$Node =
  | void
  | null
  | boolean
  | number
  | string
  | React$Element<any>
  | React$Portal
  | Iterable<React$Node>;

错误模板是:

Error: src/js/Components/RouterAware.js:8
  8: const RouterAware = (props: Props) => <div>{props.children}</div>;
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function. This type is incompatible with
137:   | React$StatelessFunctionalComponent<Props>
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ object type. See lib: /private/tmp/flow/flowlib_116f8cac/react.js:137
  Callable property is incompatible:
      8: const RouterAware = (props: Props) => <div>{props.children}</div>;
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function. This type is incompatible with
    122:   (props: Props, context: any): React$Node,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function type. See lib: /private/tmp/flow/flowlib_116f8cac/react.js:122
      This parameter is incompatible:
          8: const RouterAware = (props: Props) => <div>{props.children}</div>;
                                         ^^^^^ object type. This type is incompatible with
        144:     Component: React$ComponentType<{| ...ContextRouter, ...P |}>
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ object type. See lib: ../../../flow-typed/npm/react-router-dom_v4.x.x.js:144
          Property `children` is incompatible:
              5:   children: Node
                             ^^^^ <Specific union type here>. This type is incompatible with
             35:   <RouterAware>
                   ^^^^^^^^^^^^^ React children array. See: src/js/Root.js:35

通过将children: Node定义更改为children: Node[],可以修复这些流错误。

然而,这看起来似乎是错误的,甚至可能是react-router-dom定义的问题。我之所以这么说是因为没有withRouter包装调用,定义就可以使用简单的children: Node按预期工作,只有一个或多个孩子。

要添加到混淆/问题,现在如果使用单个子项调用组件:

const Root = () => (
  <RouterAware>
    <div>One</div>
  </RouterAware>
);

流量错误在children: Node[]上,消息为div, The type is incompatible with object type array.

这是预期的行为,当使用withRouter时,应该将其children道具定义为Node[](即使它没有意义,因为我需要children: Node | Node[]处理这两种情况。)

或者这是一个错误吗?我认为这与React组件如何在多个props.children=[<div>,<div>]时将子项转换为数组或单个props.children=<div>时的单个元素有关。

但即便如此,为什么它只出现withRouter。任何解释都会很感激。

0 个答案:

没有答案