💡

childrenを使ってReactComponentをWrapperにする方法(TypeScript対応)

2021/11/03に公開

React初学者の頃にちょっと混乱するchildrenに関して書きます.

Reactの関数Componentについて

まず,ReactでComponentを作成するときはこんな感じで書きます.

const Button = (props) => {
  return (
    <button>
      {props.label}
    </button>
  );
};

あるいはこう書いても良いでしょう.(私はこちらのほうが一般的で好まれる印象があります)

const Button = ({ label }) => {
  return (
    <button>
      {label}
    </button>
  );
};

どちらでも良いですが,後者は分割代入で引数を受け取る形で,propsの中のlabelのみを受け取る書き方です.(前者は使用時にprops.labelと書きpropsの中のlabelを呼び出す形式です.)

このComponentはこんな感じに使用します.

const App = () => {
  return (
    <div>
      <Button label='押すなよ!絶対に押すなよ!' />
    </div>
  );
};

これは(propsの中の)labelという名前で押すなよ!絶対に押すなよ!というテキストを渡しています.

関数ComponentをWrapper形式で使う

しかし,以下のように開始タグと終了タグを使ってWrapper形式で書きたい場合もあります.

const App = () => {
  return (
    <div>
      <Button>
				押すなよ!絶対に押すなよ!
			</Button>
    </div>
  );
};

このように書くと押すなよ!絶対に押すなよ!というテキストはlabelではなく,(propsの中の)childrenと名前でButtonのComponentに渡ることになります.

ButtonのComponentをこう書き換える必要があります.

const Button = ({ children }) => {
  return (
    <button>
      {children}
    </button>
  );
};

これでButtonのComponentはWrapper形式で使用することができるようになりました.

TypeScriptの場合

TypeScriptの場合はおそらくpropsに型をつけることになる.ここではFCとVFCについて補足説明的な感じで書いておきます.

import { FC } from 'react'

type Props = {
	/* 他のpropsの型 */
}

const Button: FC<Props> = ({ children, /* 他のprops */ }) => {
  return (
    <button>
      {children}
    </button>
  );
};

FCの型にはchildrenが含まれていますので,特別な記述は必要なくWrapper形式でchildrenが使用できます.

import { VFC, ReactNode } from 'react'

type Props = {
	children: ReactNode;
	/* 他のpropsの型 */
}

const Button: VFC<Props> = ({ children, /* 他のprops */ }) => {
  return (
    <button>
      {children}
    </button>
  );
};

VFCの型にはchildrenが含まれていないため,上記のように自分で定義してあげる必要があります.

Discussion