流程:如何访问 children.type.displayName

Flow: How do I access children.type.displayName

如果子项是我希望使用显示名称的组件类型,我有一个组件将应用一些额外的逻辑。

const ToggleButton = ({
  children,
}) => {
  // ...

  const isIcon = children?.type?.displayName === 'Icon';

  // ...
}

当传递字符串、组件、组件列表时,代码运行完美。但是当我添加流量时,它开始抱怨说:

Cannot get `children?.type` because property `type` is missing in `$Iterable`

我正在使用 React.Node 但我应该将儿童定义为不同类型吗?

// @flow

const ToggleButton = ({
  children: React.Node,
}) => {
  // ...

  const isIcon = children?.type?.displayName === 'Icon';

  // ...
}
const isIcon = children?.type?.displayName === 'Icon';

表示children可以是null/undefined。但是,在流程定义中,您没有指定。

所以这样做:

const ToggleButton = ({
  children?: React.Node,
}) => {
  // ...

  const isIcon = children?.type?.displayName === 'Icon';

  // ...
}

React 有一个名为 React.isValidElement 的函数,但问题是在流程中它不进行类型验证。

相反,我创建了一个类型安全的谓词函数来帮我处理这个问题

export default (obj: React.Node, name?: string): boolean %checks => (
  !!obj
  && typeof obj !== 'boolean'
  && typeof obj !== 'string'
  && typeof obj !== 'number'
  && typeof obj === 'object'
  && !!obj.type
  && (name ? !!obj.type?.displayName && obj.type.displayName === name : !!obj.type)
);

并且可以通过这种方式使用它来验证 displayName 是否符合我的预期

const isIcon = isReactElement(children, 'Icon');