【React】childrenの使い方 と 型定義propTypes

Reactでは、子要素を扱うときに、そのようなメソッドが存在するわけではないですが、”children”というものを、共通認識で暗黙の了解で使用します。

そのchildrenの使い方についてまとめました。

子要素を渡すという概念が、通常のpropsで渡す方法と少し異なり、戸惑ったので整理しました!

childrenはどんなときに使うのか?

子要素を変数にしたいとき。

例えば、ボタンの、デザインは共通にしたいが、表示文字だけ変えたい!といったときなどなど…

childrenを使うことの最大のメリットは、呼び出す親側でchildrenの要素を変更できることにあります。

通常のコンポーネントだと、子コンポーネント側でしか値を変えられず、親側で値を変えられません。

一番シンプルに使ってみる

export const Parent = (props) => {
  const { children } = props

  return <h1>{children}</h1>
}

Parentというコンポーネントを作成し、childrenという名前の通り、Parentの子要素がpropsで渡されるため、それを分割代入し、<h1>タグに囲まれたところに表示する。

この<h1>タグに囲まれた要素の中身はpropsの渡し元であるApp.jsファイル内のParent内で記述されたものです。

import { Parent } from "./Parent"

function App() {
  return (
    <Parent>
      childrenに入るよ!
    </Parent>
  );
}

export default App;

なんかこれだとあまりchildrenのありがたみを感じないですが、
例えば<h1>が凝った作りのボタンで、且つ、App.jsファイル内のみでなく、いろんなところで使用する場合、その中の表示文のみの変更で済んだら楽ですよね。

使い方はそんな感じです。

ここに、propsで渡した場合を追加して、その違いを見比べてみましょう!

propsにはchildという名前を付けています。

export const Parent = (props) => {
  const { children, child } = props;

  return (
    <h1>
      {children}
      {child}
    </h1>
  );
};

import { Parent } from "./Parent"

function App() {
  const child = "propsに渡す値だよ!";
  return (
    <Parent child={child}>
      childrenに入るよ!
    </Parent>
  );
}

export default App;

propsでは、変数で定義された値を渡しているのに対し、childrenでは、コンポーネントが持つ中身を全て渡すことができます。

headerでchildrenを使用する

headerをコンポーネント化する場合、header以下の要素をchildrenにまとめてしまうことができます。

export const Header = (props) => {
  const { children } = props
  return (
    <>
      <div style={{ height: "50px", backgroundColor: "green" }}>ヘッダー</div>
      {children}
    </>
  )
}

Headerというコンポーネントを作成し、高さ50px、背景色緑のヘッダーを作成し、その下に、childrenとしてpropsで渡される要素を表示する。

App.js側で、Headerの子要素、つまりchildrenは、ヘッダー以下に表示される要素となる。

import { Parent } from "./Parent"
import { Header } from "./Header"

function App() {
  return (
    <Header>
      <Parent>
        childrenに入るよ!
      </Parent>
      <Parent>
        これもchildrenに入るし
      </Parent>
      <Parent>
        これもchildrenに入るよ!
      </Parent>
    </Header>
  );
}

export default App;

これによりできたのがこちら

ちなみに、これをchildrenを使わず書く場合、このように書くこともできます。

export const Header = () => {
  return <div style={{ height: "50px", backgroundColor: "green" }}>ヘッダー</div>
}

import { Parent } from "./Parent"
import { Header } from "./Header"

function App() {
  return (
    <>
      <Header />
      <Parent>
        childrenに入るよ!
      </Parent>
      <Parent>
        これもchildrenに入るし
      </Parent>
      <Parent>
        これもchildrenに入るよ!
      </Parent>
    </>
  );
}

export default App;

Headerコンポーネントをそのまま入れ込んでいます。

この場合、こちらのほうが、シンプルに書けますね。用途に合わせて使い分けられるといいですね。

PropTypes

ちょっと待っください!これら紹介した childeren の使い方では少し不親切です。

例えば、冒頭に紹介したこちら!

export const Parent = (props) => {
  const { children } = props

  return <h1>{children}</h1>
}

propsとしてchildrenが渡ってくることはわかりました。でも、このchildrenに何が渡ってくるかってどうやってわかるんでしょうか?

コンポーネント名をParentにしているので、Parentコンポーネントが使われているところを探しに行く。

それでもいいですね。というかそれしかないですね。

しかし、このファイル内で一発でわかった方がより楽ちんですよね。

それを実現するのが、propTypes

それでは具体的な使い方を見ていきましょう!

まずはprop-typesというライブラリをインストールします。

$ npm show prop-types

まずはこちらで、最新のバージョンを確認し、確認ができたところで、そのバージョンを指定してインストールします。

$ npm install prop-types@15.8.0

これでインストールは完了です。

あとはコードの方に付け加えていきます。

import { string } from 'prop-types';

export const Parent = (props) => {
  const { children } = props

  return <h1>{children}</h1>
}

Parent.propTypes = {
  children: string.isRequired,
};
  • prop-typesから型stringをimport
  • 渡ってくるpropsの型をstringで指定する
  • isRequiredとして必須であることを明示する

これでpropsを受け取るファイル内でどんな型のpropsが渡ってくるか把握できるようになりました。

型指定をすることでバグが起こりにくくすることができました。

変数がisRequiredでないときの指定方法

値が必須の場合は上記のようにisRequiredとすればよかったですが、必須でない場合、default値を設定します。

例えば、boolean型で、default値がfalseの場合、以下のように指定します。

Parent.defaultProps = {
  bang: false,
};

宣言可能な型

PropTypesで宣言が可能な型には以下があります。

array, object, bool, func, number, string, symbol

また、上記のような型だけでなく、値を指定することも可能。

例えば、OpenかCloseかをチェックする場合、以下のようにoneOfを使用し、enumの形で指定することができます。

App.protoTypes = {
  status: PropTypes.oneOf(["Open", "Close"])
}

型チェックについて

上記では、PropTypesによる型チェックをまとめました。

他にも、型チェックの方法は、Proptypesを含め、以下の3種類があります。

  • PropTypes
  • Flow
  • TypeScript

PropTypeはFlowやTypeScriptが登場する前に推奨されていました。

今やTypeScriptは当たり前に使われているので、TypeScriptについてはこちらの記事をご参照ください。

Flowについてもこちらにまとめておりますのでご覧ください。

以上、最後までお読みいただきありがとうございました。

コメント