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