ReactJs:this.props.childrenのPropTypeはどうあるべきですか?


265

子をレンダリングする単純なコンポーネントを考える:

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

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

export default ContainerComponent;

質問:子供の小道具のpropTypeはどうあるべきですか?

オブジェクトとして設定すると、複数の子を持つコンポーネントを使用すると失敗します。

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

警告:失敗したプロップタイプ:に 提供されたchildrenタイプの無効なプロップ、予期された。arrayContainerComponentobject

配列として設定した場合、子を1つだけ指定すると失敗します。

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

警告:失敗したプロップタイプ:ContainerComponentに提供されたタイプオブジェクトの無効なプロップ子、予期される配列。

アドバイスしてください、私は子要素のpropTypesチェックを実行するだけでいいですか?


あなたはたぶんnode
lux


2
より多くのオプションを説明する以下の私の回答を参照してください。ただし、コンポーネントの子を探している場合は、PropTypes.elementです。PropTypes.nodeは、レンダリング可能なすべてのものを記述します-文字列、数値、要素、またはこれらの配列。これがあなたに合うなら、これが道です。
ggilberth 2017

回答:


369

この利用のようなものを試してみてくださいoneOfTypeまたはPropTypes.node

import PropTypes from 'prop-types'

...

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

または

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

1
残念ながら、それは、単一の子の場合、同じエラーで失敗:「警告:失敗した小道具の種類:無効な小道具childrenタイプのobject。...配列を期待します」
d3ming

25
うまくいきました!最も簡単な解決策はでchildren: PropTypes.node、どちらの場合でも機能しました。提案をありがとう=)
d3ming

6
この回答をより明確にする唯一のことは、@ ggilberthの回答に似たメモを含めて、React.PropTypes.nodeレンダリング可能なオブジェクトについて説明することです。
theotherjim 2017年

配列は必要ありませんPropTypes.node。それは次の修正を処理します:何もない、文字列、単一の要素、いくつかの要素、フラグメント、コンポーネント。
Dima Tisnek

38

私にとっては、コンポーネントによって異なります。何を入力する必要があるかがわかっている場合は、排他的に指定するか、以下を使用して複数のタイプを指定する必要があります。

PropTypes.oneOfType 

しかし、ほとんどの場合、多くの種類の子を持つことができるより一般的なコンポーネントで、私は使用して満足しています:

PropTypes.any

Reactコンポーネントを参照したい場合は、

PropTypes.element

とはいえ、

PropTypes.node

文字列、数値、要素、またはこれらの配列など、レンダリング可能なすべてのものを記述します。これがあなたに合うなら、これが道です。


7
Proptypes.anyあまりにも一般的なタイプです。エスリントはそれに満足していません。
Alex Shwarc 2017

20

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,
}

12

ここでの答えは、子供を正確にチェックすることを完全にはカバーしていないようです。nodeそしてobject、あまりにも許容されている、私は正確な要素をチェックしたいです。これが私が最終的に使用したものです:

  • oneOfType([])単一または子の配列を許可するために使用します
  • 使用shapeしてarrayOf(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


5

コンポーネントタイプと完全に一致させたい場合は、これをチェックしてください

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
  ])
}

2

カスタムpropTypesを試してください:

 const  childrenPropTypeLogic = (props, propName, componentName) => {
          const prop = props[propName];
          return React.Children
                   .toArray(prop)
                   .find(child => child.type !== 'div') && new Error(`${componentName} only accepts "div" elements`);
 };


static propTypes = {

   children : childrenPropTypeLogic

}

フィドル


0

例:

import React from 'react';
import PropTypes from 'prop-types';

class MenuItem extends React.Component {
    render() {
        return (
            <li>
                <a href={this.props.href}>{this.props.children}</a>
            </li>
        );
    }
}

MenuItem.defaultProps = {
    href: "/",
    children: "Main page"
};

MenuItem.propTypes = {
    href: PropTypes.string.isRequired,
    children: PropTypes.string.isRequired
};

export default MenuItem;

画像:予想されるタイプが異なる場合、コンソールにエラーが表示されます

画像:予想されるタイプが異なる場合、コンソールにエラーが表示されます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.