個人的難敵「props」とは?stateとの関連も含めてオレオレ解説
さて前回はReactの概要的なところから最終的にはstateを使ったカウントアッププログラムまでを説明しました。
前回のような単純なプログラムであればstateだけでも確かにいけるのですが、それではまだReactの恩恵に預かっているとは言えないよう。
今回ご紹介するのは主に「props」について!
私はこのpropsというものがよくわからなすぎて悶絶していたこともあり、Reactの中で一番の難敵?と思っています...
「stateとpropsとは?」という記事がよくありますが、前回も言ったように学び始める際にはこの二つは「分離して考えた方が良さそう」というのが個人的な見解です。
前回はstateを使ってカウントアッププログラムを作成してみましたので、今回もわかりやすいようにこのプログラムを踏襲してpropsについてご紹介したいと思います。
codepen.io
今回作成したものは前回作成したカウントアッププログラムと実行結果を同じもの。
そして前回作成したものはこちらです。↓
codepen.io
こちらではCountクラスのstate「count」をそのままCountクラスのrenderメソッドで描画しています。
しかし、今回作成したものでCountクラスのstate「count」を描画しているクラスはCountではなく「CountNumber」というクラス。
(余談ですがReactではクラスを定義する際に最初の文字が大文字でないと怒られるので注意です...パスカルケース?って言うようですよ...
そして今回作成したものと前回作成したもので違う点がクラス以外にもう一つ。
それが「Count」クラスの中にある「constructor」の「props」。
ここでようやくpropsが出てきましたね〜
propsはproperties(プロパティ)の意味のようで、そのクラスがもつプロパティと考えて良さそう。
しかしこれとstateの違いが最初はわからなかった...(今も曖昧ですが)
ですが先ほども言ったようにstateとpropsを一度分離してみるとわかりやすかったです!
前回作成したものはstateだけで動いてしますが、今回作成したものはpropsも使って動いています。
この二つでの違いはズバリ「新しいクラスに値を渡すかどうか」でしょう。
今回はCountクラスで定義したcountというstateをCountNumberというクラスに渡しています。
この時に重要なのがpropsでpropsを使うことで、自身のもつstateを子に渡すことができます。
そしてpropsを利用してstateを渡すお作法がこちら。
constructor(props) { super(props) this.state = { count: 0 }
前回のものをみるとわかりますが、constructor( )とprops( )の引数に(props)が与えられています。
これは正直わからないのでpropsを使って値を渡すために必要なお作法だと覚えておきましょう。
これを使うことで、子のクラスに自身のstateを渡すことができるのですが、渡し方と受け取り方にもあるお作法が。
渡し方のお作法
<CountNumber count = {this.state.count} />
受け取り方のお作法
<p> {this.props.count} </p>
こちらが渡し方と受け取り方のお作法になります。
私がこのようなクラス作ってプロパティ作ってクラスメソッドを...というような言語に慣れていなかったため困惑したのだと思いますが、よくよく考えるとstateとpropsの違いは上記のお作法で完結しているのではないでしょうか?
自身のクラスの状態を表すプロパティであるstateは「this.state」で参照することができるので自クラスのメソッドであるrenderで渡すには自身(this)のstateを参照し、適当な変数に入れて子クラス(他のコンポーネント)に値を渡すことができるわけですね。
少し混乱すると思いますが、このように複数のコンポーネントを管理する場合はまずメインのコンポーネントを作成した後に他のコンポーネントの骨組みを作ってしまった方がわかりやすい気がします。
今回の場合はただカウントアップしていく「数字」のみを表示するコンポーネント「CountNumber」を作って、その後にメインコンポーネントである「 Count」でCount自身のstateをCountNumberに渡すようにしています。
そして前回抜けていた関数を実行する場合にもあるお作法があります。
<button onClick={this.countUp.bind(this)}>push!</button>
Reactではこのように現在のHTMLではあまりよしとされていない「onclick」を使ってイベントを設定することができます。
ここで関数を設定するお作法は「{this.countUp.bind(this}」というもの。
CountクラスではクラスメソッドとしてCountUpというものを定義していますが、これをrenderメソッド内で参照するにはstateと同じようにthisが必須。
しかし、ここで重要なのは「bind」です。
動かしてみるとわかりますが、このbindがないとこのプログラムは動きません。
これもよくわかっていないのですが、bindとはそもそもbind(オブジェクト)のようにあるオブジェクトに関数を紐づけて新しい関数を作成するというもの。
thisについてはまだまだ勉強中ですので詳しいことはお話できませんが、ここで言えば自身のクラスにこのクラスメソッドを紐づけている、ということで良さそうです。
このbindを与えることで関数が実行できるようになるのでこれも覚えておきましょう。
そして関数を渡す場合のお作法もほぼstateを渡すような場合と同じです。
渡し方のお作法〜関数編〜
<CountNumber countUp = {this.countUp.bind(this)} />
受け取り方のお作法〜関数編〜
<button onClick={this.props.countUp} >push! </button>
こちらもpropsを通じて受け渡しをすることができるんですね。
この例でもわかるように、とにかくpropsはstateやメソッドなどクラスで定義されているものを受け渡しするためのもの、と考えていいです。
stateは自身の状態を定義するだけのものなのでここがpropsと違いますね。
さて、propsとstateの違い、また関数の実行の仕方についてオレオレ解説していきましたがいかがでしたでしょうか?
Reactを触っていく中でも感じましたがやはり「触ってみることが大事」ということをひしひしと感じましたね。
一通りReactの概要やお作法に関しては解説したつもりなので、次回はReactをnpmで環境構築をする場合、少し発展?してAPIからデータを取得して利用する、といったことについてお話していきたいと思います!