使用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
。任何解释都会很感激。