はじめに
前回では、親コンポーネントから値を流し込んで、その値をリスト表示しました。
今回は、その画面表示した値に、画面からの入力値を追加していくというコードを書いていきます。
一旦ここまでできれば、親-子コンポーネントの関係、値表示、イベントハンドルまでが出来るようになりますので、とりあえずReactでの開発ができるようになってくる、はずです。実践で使うにはまだ足りませんが入門としては最低限やったはずです。
コードを書いていく
前回書いたリスト表示するコードの、クラス定義終了部分~var my_items宣言までの間に、下記を追記します。
[javascript] class ListApp extends React.Component {
constructor(props){
super(props);
this.state = {
items: props.items
};
}
render(){
return(
<div>
<h3>List App</h3>
<div>
<input id="ListApp-name" placeholder="name" />
<input id="ListApp-text" placeholder="text" />
<button onClick={this.handleClick.bind(this)}>add</button>
<MyList items={this.state.items} />
</div>
</div>
)
}
handleClick(event){
this.setState({
items: this.state.items.concat({
name: document.getElementById("ListApp-name").value,
text: document.getElementById("ListApp-text").value
})
});
}
}
[/javascript]
そして、最後のReactDOM.renderの第1引数を下記のように修正します。
<ListApp items={my_items} />
この部分は、今回追加したクラスを最初に画面に表示したいのでタグ名を修正しただけですね。
ListAppについて
constructor
superの部分は前回と同じです。
this.stateの部分が今回新しい部分で、そのコンポーネント内部に状態(値)を持ちたい場合にstateとして定義します。
今回は、リスト表示部の値を保持しておきたいので、this.stateの定義をし、外から受け取ったprops.itemsをitemsプロパティにセットしておきます。
render
前回作成したMyListを内包しています。
こんな感じでコンポーネントの再利用というか、が出来るのがReactの嬉しいところらしいです。
MyListコンポーネントに、リスト表示は全てお任せしますので、前回のようにitems属性にリスト表示させたいthis.state.itemsを渡します。
もうひとつの大きな修正点としては、button要素とクリックイベントです。
buttonはただのbutton要素で、onClickもHTML純正のイベント付与の属性ですね。
ここで、this.handleClick.bind(this)をonClickに渡しています。this.handleClickはrenderの次のメソッドであるhandleClickメソッドを指しています。bind(this)は、おまじないとして付与しておいて下さい。
何故bind(this)するのかというと、こちらの記事に書いてありますが、ES6でReactComponentを作成した場合、イベントハンドラでthisがundefinedになるため、thisを明示的に渡してあげる必要があります。
handleClick
pureJSのようなJavascriptのイベントハンドラです。eventオブジェクトを引数として受け取ります。
が、このeventオブジェクトはHTML+pureJSのオブジェクトとは異なるようです。
this.setStateメソッドにて、constructorで宣言したstateオブジェクトに値をセットすることができます。
今回は、リストを更新したいので、itemsプロパティを更新します。
ちなみに、今回は面倒だったのでdocument.getElementByIdにてinput要素の値を取得していますが、たぶんあんまり推奨されない方法かなと思います。
真面目にやるのであれば、input要素にonChangeを付与して、クラスにchangeHandleメソッドを作成し、そのメソッド内でstateの値を更新して、handleClick内ではstateの値をもとにitemsを更新する、というのが望ましいと思われます。
結果
こんな感じになります。
次回からは、npmを使ってwebpackやbabelをインストールして、webpackベースでトランスパイル&バンドルしていく、的なところをやっていこうと思います。
今回は以上です!
次回はこちら。
https://tasokori.net/%E3%80%90react%E3%80%91react%E3%81%AB%E7%88%86%E9%80%9F%E3%81%A7%E5%85%A5%E9%96%80%E3%81%99%E3%82%8B4%E3%80%82webpack%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%90%E3%83%B3%E3%83%89%E3%83%AB%E3%81%99/