类型检查反应儿童

时间:2017-03-13 17:30:42

标签: javascript html validation reactjs react-jsx

问题

如何确认通过道具收到的反应元素(例如children)在我的渲染方法中属于给定类型?

实施例

说我有一个List元素和一个ListItem元素。在List的渲染方法中,我想查找所有已传递的子项,并对ListItem个任何子项执行特殊操作。

我确实找到了一个可行的实现,但只是在试错之后。请参阅下面的代码。 (React 15.4.2)

List.jsx

import ListItem from 'list-item';

...

React.Children.map(children, child => {
  console.log(child);     // function ListItem() { ... }
  console.log(ListItem);  // function ListItem() { ... }

  if (isListItem(child)) {
    return (...);
  }
  return child;
})

// this implementation does not work
isListItem(element) {
  return (element.type === ListItem);
}

// this implementation does work, but might break if I'm using something like uglify or if I use `react-redux` and `connect()` ListItem (as that will change the display name)
isListItem(element) {
  return (element.type.displayName === 'ListItem');
}

// this implementation does work
isListItem(element) {
  return (element.type === (<ListItem />).type);
}

ListItem.jsx

class ListItem expends React.component {
  ...
}

export default ListItem;

所以,最后一个实现似乎有效,但为什么第一个实现不起作用?我在反应文档中找不到与此相关的任何材料,尽管我确实发现了一些关于同一事情的堆栈溢出问题。但是,这些问题中提供的答案表明第一个实现应该有效(尽管它们适用于旧版本的React)

相关链接

1 个答案:

答案 0 :(得分:1)

虽然这个问题很旧,但我在使用react-hot-loader时遇到了这个问题,花了我一段时间才找到this GitHub issue,解释了为什么这样做。

  

这是有意的,react-hot-loader @ 3补丁React.createElement(<ImportedComponent />)等效于React.createElement(ImportedComponent),因此它为您的组件(而不是原始组件)返回代理包装的元素,这是一部分of允许在不卸载的情况下替换组件上的方法。

     

-@nfcampos

除了您发现的方法之外,RHL现在还提供了areComponentsEqual() function with a dedicated section in their README

import { areComponentsEqual } from 'react-hot-loader'

const element = <Component />
areComponentsEqual(element.type, Component) // true