ReactJs:this.props.children 的 PropTypes 应该是什么?

IT技术 reactjs jsx react-proptypes
2021-03-31 10:33:48

给定一个呈现其子项的简单组件:

class ContainerComponent extends Component {
  static propTypes = {
    children: PropTypes.object.isRequired,
  }

  render() {
    return (
      <div>
        {this.props.children}
      </div>
    );
  }
}

export default ContainerComponent;

问题:children prop的propType应该是什么?

当我将它设置为一个对象时,当我使用具有多个子项的组件时它会失败:

<ContainerComponent>
  <div>1</div>
  <div>2</div>
</ContainerComponent>

警告:失败的props类型: 提供给,预期children的类型的props无效arrayContainerComponentobject

如果我将它设置为一个数组,如果我只给它一个孩子,它就会失败,即:

<ContainerComponent>
  <div>1</div>
</ContainerComponent>

警告:失败的props类型:提供给 ContainerComponent 的类型对象的无效props子项,预期数组。

请指教,我是否应该不打扰对子元素进行 propTypes 检查?

6个回答

尝试使用oneOfTypePropTypes.node

import PropTypes from 'prop-types'

...

static propTypes = {
    children: PropTypes.oneOfType([
        PropTypes.arrayOf(PropTypes.node),
        PropTypes.node
    ]).isRequired
}

或者

static propTypes = {
    children: PropTypes.node.isRequired,
}
不幸的是,它在单个子案例中失败并出现相同的错误:“警告:失败的道具类型:无效的道具children类型object......期望一个数组。”
2021-06-03 10:33:48
不需要数组,只需要PropTypes.node. 处理以下更正:无、字符串、单个元素、几个元素、片段、组件。
2021-06-09 10:33:48
我需要把这个答案挂在我房间墙上的某个地方。我一次又一次地回到这里。:)
2021-06-10 10:33:48
那行得通!最简单的解决方案是children: PropTypes.node,这两种情况都适用。感谢您的建议 =)
2021-06-17 10:33:48
唯一能让这个答案更清晰的事情是,如果您包含一个类似于@ggilberth 的答案的注释来解释React.PropTypes.node描述任何可渲染对象。
2021-06-17 10:33:48

对我来说,这取决于组件。如果您知道需要填充什么,那么您应该尝试使用以下方法单独指定或指定多种类型:

PropTypes.oneOfType 

如果你想引用一个 React 组件,那么你会寻找

PropTypes.element

虽然,

PropTypes.node

描述任何可以渲染的东西——字符串、数字、元素或这些东西的数组。如果这适合你,那么这就是方法。

对于非常通用的组件,它们可以有多种类型的子组件,您也可以使用以下组件 - 尽管请记住,eslint 和 ts 可能对这种缺乏特异性感到不满意:

PropTypes.any
Proptypes.any也意味着object如果您通过object.
2021-05-29 10:33:48
Proptypes.any是太常见的类型。埃斯林特对此并不满意。
2021-06-15 10:33:48
如果您打算使用any,您应该完全节省使用 propTypes 的时间。
2021-06-19 10:33:48

PropTypes 文档有以下内容

// Anything that can be rendered: numbers, strings, elements or an array
// (or fragment) containing these types.
optionalNode: PropTypes.node,

因此,您可以使用PropTypes.node来检查对象或对象数组

static propTypes = {
   children: PropTypes.node.isRequired,
}

这里的答案似乎并没有完全涵盖对孩子的确切检查。node并且object过于宽松,我想检查确切的元素。这是我最终使用的:

  • 使用oneOfType([])允许单个或儿童阵列
  • 分别对单个子项和子项数组使用shapearrayOf(shape({}))
  • 使用oneOf的子元素本身

最后,是这样的:

import PropTypes from 'prop-types'
import MyComponent from './MyComponent'

children: PropTypes.oneOfType([
  PropTypes.shape({
    type: PropTypes.oneOf([MyComponent]),
  }),
  PropTypes.arrayOf(
    PropTypes.shape({
      type: PropTypes.oneOf([MyComponent]),
    })
  ),
]).isRequired

这个问题帮助我更清楚地解决了这个问题:https : //github.com/facebook/react/issues/2979

如果要完全匹配组件类型,请检查此

MenuPrimary.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(MenuPrimaryItem),
    PropTypes.objectOf(MenuPrimaryItem)
  ])
}

如果您想完全匹配某些组件类型,请检查此

const HeaderTypes = [
  PropTypes.objectOf(MenuPrimary),
  PropTypes.objectOf(UserInfo)
]

Header.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.oneOfType([...HeaderTypes])),
    ...HeaderTypes
  ])
}