LoginSignup
2
1

More than 5 years have passed since last update.

30 Days of React を意訳していく Day8 - PropTypes

Posted at

はじめに

Fullstack React: 30 Days of React の意訳です。

ちょいちょい読んでるのでせっかくなので訳そうと思った次第。飽きるまで続きます。かなり意訳です。

※補足: ってなってるのは、私の補足や思ったことなどです

本編

今日は再利用可能なコンポーネントの作り方とチームやアプリ感でそれらをシェアする方法を見て行きます。

なんとか2週目に入りましたね。ここまでは、基本的なReactの機能(props, state, life-cycle hooks, JSX, など)を学びました。このセクションではコンポーネントのアノテーティングを見ていきます。

PropTypes

コンポーネントの中では、propsがかなりたくさん使われているのに気がついたかもしれません。ほとんどの場合、これらのpropsには特定の型の値(stringやobjectなど)が渡されることを想定すると思います。Reactは、簡単にコンポーネントのAPIを公開できるようにするために、これらの型を定義、検証するためメソッドを提供します。

これはドキュメント化以外にも再利用可能なコンポーネントを作るという点においても良いプラクティスです。

React.PropTypes オブジェクトを使うと、コンポーネントのプロパティが何の型であるべきかを定義することができます。

ES6クラススタイルのpropTypesメソッドを使ってプロパティの型を定義することができます。

class Clock extends React.Component {
  // ...
}

Clock.propTypes = {
  // key is the name of the prop and
  // value is the PropType
}

React.createClass() を使う場合は以下のようになります。

const Clock = React.createClass({
  proptypes: {}
});

コンポーネントのプロパティ名と型のセットを持つオブジェクトによって、プロパティの型が何であるべきかを定義することができます。

数日前に作ったHeaderコンポーネントをtitleプロパティを文字列型と定義する例は以下のようになります。

class Header extends React.Component {
  // ...
}

Header.propTypes = {
  title: React.PropTypes.string
}

React.PropTypes に使える多くの型があります。使える型のリストを見てみましょう。

Basic types

type example class
String hello React.PropTypes.string
Number 10, 0.1 React.PropTypes.number
Boolean true / false React.PropTypes.bool
Function const say => (msg) => console.log("Hello world") React.PropTypes.func
Symbol Symbol("msg") React.PropTypes.symbol
Object {name: 'Ari'} React.PropTypes.object
Anything whatever, 10, {}
A rendererable 10, 'hello' React.PropTypes.node

レンダリング可能ならどんな型でもよい場合には、React.PropTypes.node を使うことができます。

Clock.propTypes = {
  title: React.PropTypes.string,
  count: React.PropTypes.number,
  isOn: React.PropTypes.bool,
  onDisplay: React.PropTypes.func,
  symbol: React.PropTypes.symbol,
  user: React.PropTypes.object,

  name: React.PropTypes.node
}

ここまで、プロパティを使って、親コンポーネントから子コンポーネントにコミュニケーションする方法を見てきました。また、子コンポーネントから親コンポーネントを関数を使ってコミュニケーションする方法も見ました。この方法は子コンポーネントから親コンポーネントを操作する場合に非常に多く使うパターンなのでよく覚えておきましょう。

Collection types

イテレータブルなコレクションをプロパティに渡すこともできます。コンポーネントのproptypeを配列として宣言するために、React.PropTypes.arrayアノテーションを使用できます。

また、配列にReact.PropTypes.arrayOf([]) を使用して特定の型のオブジェクトだけを持つように要求することもできます。

type example class
Array [] React.PropTypes.array
Array of numbers [1, 2, 3] React.PropTypes.arrayOf([type])
Enum ['Red', 'Blue'] React.PropTypes.oneOf([arr])

React.PropTypes.oneOfType([types]) を使って、特定の型の配列を定義することもできます。

Clock.propTypes = {
  counts: React.PropTypes.array,
  users: React.PropTypes.arrayOf(React.PropTypes.object),
  alarmColor: React.PropTypes.oneOf(['red', 'blue']),
  description: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.instanceOf(Title)
    ]),
}

Object types

決まった形式のオブジェクトや特定のクラスのインスタンスを定義することもできます。

type example class
Object {name: 'Ari'} React.PropTypes.object
Number object {count: 42} React.PropTypes.objectOf()
Instance new Message() React.PropTypes.instanceOf()
Object shape {name: 'Ari'} React.PropTypes.shape()
Clock.propTypes = {
  basicObject: React.PropTypes.object,

  numbers: React.PropTypes
    .objectOf(React.PropTypes.numbers),

  messages: React.PropTypes
    .instanceOf(Message),

  contactList: React.PropTypes.shape({
    name: React.PropTypes.string,
    phone: React.PropTypes.string,
  })

React types

親から子へReactの要素を渡すこともできます。これはテンプレートを定義し、そのテンプレートをカスタマイズするのにとても役にたちます。

type example class
Element React.PropTypes.element
Clock.propTypes = {
  displayEle: React.PropTypes.element
}

エレメントを使う場合には、単一の要素を渡す必要があります。複数の要素を渡すことはできません。

// 正しくない
<Clock displayElement={
  <div>Name</div>
  <div>Age</div>
}></Clock>

// 正しい
<Clock displayElement={
  <div>
    <div>Name</div>
    <div>Age</div>
  </div>
}></Clock>

Requiring types

.isRequired をつけることで、そのプロパティを必須にすることができます。

Clock.propTypes = {
  title: React.PropTypes.name.isRequired,
}

そのプロパティが親から渡されないと動作しないような場合に、プロパティを必須にするのはとても役にたちます。

Custom types

最後に、関数を渡すことでカスタムタイプを定義することもできます。これは単一のプロパティのArrayのバリデーションに使えます。バリデーションがパスしない場合、関数はErrorオブジェクトを返す必要があります。

type example class
Custom something_crazy function(props, propName, componentName) {}
CustomArray ['something', 'crazy'] React.PropTypes.arrayOf(function(props, propName, componentName) {})
Clock.propTypes = {
  userWithName: (props, propName, componentName) => {
    if (!props[propName] || !props[propName].name) {
      return new Error(
        `Invalid ${propName}: No name property defined
          for component ${componentName}`
      )
    }
  },

  usersWithNames: React.PropTypes
    .arrayOf((props, propName, componentName) => {
      if (!props[propName] || !props[propName].name) {
      return new Error(
        `Invalid ${propName}: No name property defined
          for component ${componentName}`
      )
    }
    })
}

Default props

プロパティを設定したい場合もあると思います。例えば、以前作った <Header /> にタイトルを渡さない場合でも、タイトルには何かしらのタイトルを表示する必要があります。

デフォルト値の設定には、 defaultProps を使います。

Header.defaultProps = {
  title: 'Github activity'
}

型の定義やデフォルト値の設定は、コンポーネントの再利用や開発者間のコミュニケーションに役立ちます。次にセクションではスタイルの設定について見てきます。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1