Reactでは、子要素を扱うときに、そのようなメソッドが存在するわけではないですが、”children”というものを、共通認識で暗黙の了解で使用します。
そのchildrenの使い方についてまとめました。
子要素を渡すという概念が、通常のpropsで渡す方法と少し異なり、戸惑ったので整理しました!
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についてもこちらにまとめておりますのでご覧ください。
以上、最後までお読みいただきありがとうございました。
コメント