React propsは親要素が持つプロパティ値を渡して、コンポーネント内容を動的に変化させる
ReactのPropsとは、親要素側jsから子要素のコンポーネントjs側へ受け渡せるデータ(引数)の事です。
親要素が複数のプロパティ値やデータを保持してコンポーネント側に渡す事で、同一コンポーネントの表示を動的に変更する事ができます。
Propsにより共通コンポーネント部分を使い回しする事ができ、親要素によって表示を変える事が可能です。
親要素からプロパティ値を渡せる
本記事ではReactの「Props」の受け渡しの機能について紹介します。
Propsとは、親となる要素からコンポーネントである子要素へ渡されるデータ(引数)の事を指します。
Propsとは「プロパティ:Propertys」の略称ですね。
Propsによりコンポーネント側は様々なものを取得するのですが、一番は親要素から「プロパティの値」をもらえる事でしょう。
デザインが変わるのはプロパティの値が違うから
各コンテンツのデザインが、ケースによって変わるのはなぜでしょう?
それはズバリ、各箇所で設定したCSSの「プロパティ値が違うから」です。
例えば文字の大きさが「12px」なら12pxになりますし、「24px」なら24pxになりますよね。
プロパティ値の違うCSSスタイルを複数準備する
本来こういったプロパティ値は、CSSの中に直接記述されます。
違うデザインを用意するために、違うプロパティ値のCSSスタイルを個別に用意していましたよね。
豊富なデザインを用意するのなら、その分CSSのコード量が増える事になります。
プロパティ値を親要素側が持つ
Reactでは、これらのプロパティ値をPropsによって親要素側が保持しておく事ができます。
子要素にそれが渡った時、コンポーネント内で一つのCSSスタイルが生成されます。
つまり同じCSSスタイルでも、親要素からもらうプロパティ値によって表示結果が変わる事になりますね。
表示の違いを子要素側で操作しない
わかりくいと思いますので、HTMLとCSSの例を挙げて解説しましょう。
WEBページの色違い文章
例えばWEBページの中で通常は「黒」ですが、場合により「赤文字」にする文章箇所があるとしましょう。
これをCSSでスタイリングする場合、簡単に表現すれば以下の様な記述になります。
HTML
<p class="bk">テキスト文章・テキスト文章(黒)</p> <p class="red">テキスト文章・テキスト文章(赤)</p>
CSS
.bk{ color: #333333; //黒のスタイル } .red{ color: #cc0000; //赤のスタイル }
上記の様に黒文字は「.bk」、赤の文字は「.red」のクラスで囲って表現する訳です。
ここで注目すべきは「プロパティ値以外がほぼ同じ」という事です。
色こそ違いますが、「color: …;」の記述部分は同じ記述ですよね。
2色程度ならこの位ですが、複数色を用意するならその分似た記述が必要になってきます。
親要素が色の値を持つ
ここで色の指定プロパティの値を、強引に親要素に担当させてみましょう。
HTML(指定データを保持)
<p "色:黒">テキスト文章・テキスト文章</p> <p "色:赤">テキスト文章・テキスト文章</p>
実際にはこのような書き方はしませんが、わかりやすく色情報を保持した状態にしています。
CSS(スタイリング枠のみ)
p{ color: ○○○; //親要素からの色指定が入る }
この様にCSSが色の値を親要素(HTMLソース上)からもらう事ができれば良いのです。
プロパティ値をもらったCSSがスタイリングされ、親要素上で表現されます。
親要素の渡す情報により、動的に変化する
実際のHTML・CSSのみではこのような事はできませんが、この様に動的に変わる色部分をHTML要素側が持てば良いのです。
CSS記述は共通ですが、黒が入れば黒くなり赤が入れば赤になりますよね。
これにより黒用・赤用にCSSスタイルを用意する必要が無い訳ですね。
スタイルの違いをpropsで実現
では実際にReactのPropsで、スタイリングの値を渡して構成してみましょう。
reactアプリ構成
まずは単純に以下の様な構成を作ります。
src
├—App.js…親要素
├—components
└Color.jsx…子要素
メインがApp.js、コンポ―ネットファイルがColor.jsxとなります。
App.jsの設定
import { Color } from "./components/Color"; export const App = () => { return( <Color color="black" /> <Color color="red" /> ); };
まず子要素であるコンポーネント「Color.jsx」ファイルを読み込んでいます。
Colorタグでコンポーネントファイルを2行出力しています。
この時上段でcolor="black"、下段でcolor="red"と、色の値を所持しています。
Color.jsxの設定
export const Color = (props) => { const contentstyle ={ color: props.color }; return( <p style={contentstyle}>テキスト文章</p> ); };
次にColor.jsxですが、まずexport constの部分に(props)と記述されています。
これで親要素からPropsデータが流れ込んでくる事になります。
すぐ下にあるCSS記述(contentstyle)の「props.color」部分に、親要素から渡された色(#000000など)が収まります。
returnの欄で、contentstyleスタイルが入った<p>~</p>1行を生成しています。
実行結果
出力HTMLソース
<p style="color: black;">テキスト文章</p> <p style="color: red;">テキスト文章</p>
pタグのスタイル欄に。それぞれblack;とred;が入っているのがわかります。
blackが入った行は黒く表示され、redの入った行は赤く表示されます。
Color.jsxのCSS(contentstyle)部分は、黒と赤とで表示を分けたりしていませんよね。
CSS記述は共通で、色指定部分をApp.js側で操作している事になります。
これがPropsの基本的な考え方です。
コンテンツの違いをPropsで実現
上記は、親要素が持つCSSのスタイル値を子要素に渡して構成をしていました。
Propsはスタイル要素だけでなく、コンテンツ情報も渡すことができます。
ページのtitleデータをPropsで管理
例えばWEBページでは、各ページごとにtitleテキストを変えるのは当たり前ですよね。
・TOPページのtitleタグ…「TOPページ」
・会社概要ページのtitleタグ…「会社概要」
HTMLファイルなら各ページ共通のheadタグを設けて、titleタグ内のテキストを書き換えます。
同じHTML記述が各ページごとにありますから、修正の際は手間が掛かり面倒です。
Wordpresテーマと考え方は同じ
Wordpressテーマでheader.phpを作る場合は、titleタグ内にそのページのタイトルが流れ込んでくるようにします。
テーマ部分は共通で、出力ページごとに表示されるタイトル部分が変わりますよね。
これと同様の事がReactでもできる訳です。
reactアプリ構成
src
├—Index.js…TOPページ
├—Corp.js…会社概要ページ
├—components
└Header.jsx…header用コンポーネント
Index.js
import { Header } from "./components/Header"; export const Index = () => { return( <header title="TOPページ" /> ); };
Corp.js
import { Header } from "./components/Header"; export const Corp = () => { return( <header title="会社概要ページ" /> ); };
Index.jsとCorp.jsの親要素は、それぞれコンポーネントとしてHeader.jsxを読み込んでいます。
それが<header />タグの部分に出力されます。
さらにそれぞれ「title=""」内にテキストデータを所持しています。
これがpropsで子要素のHeader.jsxの方に渡ってくる訳です。
Header.jsxの設定
export const Header = (props) => { return( …以下略 <title>{props.title}</title>; …以下略 ); };
子要素のHeader.jsxでは、()内にpropsと記載します。
親要素からのPropsデータが、return内の「props.title」のところに代入されます。
レイアウトとデータが構成され、Index.jsやCorp.jsで出力される訳ですね。
普通header内にはtitle以外に様々な記述がされるはずですが、説明の都合上<title>タグのみにしています。
実行結果
Index.js…<title>TOPページ</title>
Corp.js…<title>会社概要ページ</title>
Header.jsxが持つタグソース部分は共通で、情報自体を親要素側が持っている事になります。
こうする事でHeader.jsxのコンポーネントを使い回す事ができていますね。
複数のプロパティ値、データを保持できる
今回は<header title="○○" />という形で、titleデータを保持していましたが、他にもたくさんの情報を保持してPropsで渡せます。
たくさんのheadタグの値を保持
headerの中にはdescriptionやcssなど、他にもたくさんのタグが出てきますよね。
これらを全てPropsでコンポーネント側に渡す事ができます。
複数のPropsを入れた例
Index.jsのreturn内記述
<header title="○○" description="○○" css="○○"… />
Header.jsx
export const Header = (props) => { return( <title>{props.title}</title>; <meta name="description" content="{props.title}">; <link rel="stylesheet" href="{props.title}">; ); };
データ部分を全て親要素側で保持し、子要素はもらった複数のデータをもとに出力データを構成します。
プロパティ値も複数持てる
Propsはデータだけではなく、プロパティ値も複数を所持して渡す事ができます。
先程は黒と赤の文字の色の違いだけを動的に表現しましたが、他にもプロパティ値はたくさんあります。
例えばCSSなら、borderやbackground、margin・paddingなどですね。
先述したApp.jsとColor.jsので複数プロパティを持つ例を紹介します。
App.jsの設定
import { Color } from "./components/Color"; export const App = () => { return( <Color size="12" margin="0 0 10px 0">テキスト文章</Color> <Color size="24" back="images/back.png">テキスト文章</Color> ); };
Color.jsxの設定
export const Color = (props) => { const contentstyle ={ fontSize: "props.size", margin: "props.margin", backGround: "props.back" }; return( <p style={contentstyle}>{props.children};</p> ); };
使わないプロパティは設定自体をしなければOFFになりますし、時には「none」などで上書きすれば良い事になります。