Reactの続きです。前回はステートでsetState()、タイマー処理、イベント処理をやってみました。今回は三項演算子による条件分岐と、map()
によるループをやってみます。それではいきましょう!
【目次】
※参考:前回記事
【React】Reactプロジェクトでステートを事始め(setState()、タイマー処理、イベント処理) - クモのようにコツコツと
※参考:Reactを習得するためにやったことまとめ
qiita.com
前回のおさらい
今回も掌田さんの「React.js & Next.js入門」を参考に進める。
- 作者:掌田津耶乃
- 発売日: 2019/08/30
- メディア: Kindle版
前回作ったもの
state
でステートの初期値を設定setState()
でステートの値の更新設定(カウントアップ)onClick
でクリックイベントによるステート更新を実行
詳細は前回記事を参照
※参考:前回記事
【React】Reactプロジェクトでステートを事始め(setState()、タイマー処理、イベント処理) - クモのようにコツコツと
今回はさらに条件分岐やループなどの制御構造をやってみる。
条件分岐(三項演算子)
まずは条件分岐から。
作ってみたもの
初期値で太郎が「羊が何匹??」と聞いている。 「数える」を押すと
次郎が「羊が1匹!」と答える。
「数える」を押すと
太郎が「羊が2匹?」と聞く。
「数える」を押すと
次郎が「羊が3匹!」と答える
以下、交互に繰り返す。
以前、JSXで行った条件分岐はこちらを参照。この中の「三項演算子」を使った条件分岐を使っている。
※参考:【React】条件分岐の書き方(if文エラー回避、論理演算子、三項演算子) - クモのようにコツコツと
Appコンポーネントの変更内容
まずApp
コンポーネントにflag
キーを追加する。初期値はtrue
。
class App extends React.Component { constructor(props) { super(props); this.state = { msg1: "羊が", num: 1, msg2: "匹", message: "羊が何匹?", flag: true // 追記 }; this.countUp = this.countUp.bind(this); }
countUp()メソッドの変更内容
countUp()
メソッドでflag
の変更を追記する。
countUp(e) { this.setState((state) => ({ num: state.num +1, message: state.msg1 + state.num + state.msg2, flag: !state.flag // 追記 })); }
state.flag
の値を反対!
にするという設定。
これでtrue
はfalse
に、逆にfalse
はtrue
になる。
render()に三項演算子を追加
最後にJSXレンダリングのrender()
に三項演算子を追加
render() { return <div className="App"> <header className="App-header"> <div className="App-images"> <Img align="left" /> <Img align="center" /> <Img align="rignt" /> </div> <h1>初めてのステート</h1> {this.state.flag ? <p>太郎「{this.state.message}?」</p> : <p>次郎「{this.state.message}!」</p> } <button onClick={this.countUp}>数える!</button> </header> </div> }
h1
タグの下、flag
がtrue
だったら太郎が「○○?」という。false
だったら次郎が「○○!」という。
App.js全体
import React from 'react'; import Img from './Img'; import './App.css'; class App extends React.Component { constructor(props) { super(props); this.state = { msg1: "羊が", num: 1, msg2: "匹", message: "羊が何匹?", flag: true }; this.countUp = this.countUp.bind(this); } countUp(e) { this.setState((state) => ({ num: state.num +1, message: state.msg1 + state.num + state.msg2, flag: !state.flag })); } render() { return <div className="App"> <header className="App-header"> <div className="App-images"> <Img align="left" /> <Img align="center" /> <Img align="rignt" /> </div> <h1>初めてのステート</h1> {this.state.flag ? <p>太郎「{this.state.message}?」</p> : <p>次郎「{this.state.message}!」</p> } <button onClick={this.countUp}>数える!</button> </header> </div> } } export default App;
ループ(map())
次にループをやってみる。
作ってみたもの
「初めてのステート」の下に「はっぴいえんど」
はっぴいえんどのファーストの曲目。この部分をループで表示している。
以前、JSXで行ったループはこちら。この中のmap()
メソッドを使っている。
※参考:【React】ループの書き方(for文エラー回避、配列、map()) - クモのようにコツコツと
Appコンポーネントの変更内容
配列song
まずApp
コンポーネントにループで表示したい曲名を配列
song`に入れる
class App extends React.Component { song = [ '抱きしめたい', '空いろのくれよん', '風をあつめて', '暗闇坂むささび変化', 'はいからはくち', 'はいから・びゅーちふる', '夏なんです', '花いちもんめ', 'あしたてんきになあれ', '颱風', '春らんまん', '愛餓を' ];
コンストラクタ
次にコンストラクタでステートを設定
constructor(props) { super(props); this.state = { list:this.song }; }
list
キーに配列song
をセット
JSX設定
render()
でレンダリングするJSXを設定。
render() { return <div className="App"> <header className="App-header"> <div className="App-images"> <Img align="left" /> <Img align="center" /> <Img align="rignt" /> </div> <h1>初めてのステート</h1> <h2>はっぴいえんど</h2> <List title="はっぴいえんど(1970)" song={this.song} /> </header> </div> } }
h2
タグの下で後述するList
コンポーネントを読み込むList
のtitle
属性は文字列、song
属性はsong
Listコンポーネント:map()
でループ実行
App
コンポーネントで読み込むList
コンポーネントを作成
class List extends Component { number = 1; render () { let song = this.props.song; return ( <div> <p>{ this.props.title }</p> <ul> {song.map((item) => <Item number={this.number++} value={item} key={this.number} /> )} </ul> </div> ); } }
- グローバル変数
number
を設定。初期値は1
render ()
でJSXを設定- 変数
song
にprops
の配列song
を設定 p
タグはprops
のtitle
ul
タグの中身:配列song
の値をmap()
メソッドでループmap()
の引数は無名関数で、無名関数の引数はitem
- 無名関数の処理:後述する
Item
コンポーネントを読み込む Item
のnumber
属性はnumber
を1つ加算、value
属性はitem
、key
属性はnumber
Itemコンポーネント作成
List
コンポーネントで読み込むItem
コンポーネントを作成
class Item extends Component { liStyle = { listStyleType: "none", textAlign: "left" }; render () { return ( <li style={this.liStyle}>{this.props.number}. {this.props.value}</li> ); } }
- グローバル変数
liStyle
の値は連想配列でCSSスタイル render()
でJSXを設定li
タグの中にstyle
属性があり値はliStyle
li
タグの中身はprops
のnumber
とprops
のvalue
App.js全体
import React, { Component } from 'react'; import Img from './Img'; import './App.css'; class App extends React.Component { song = [ '抱きしめたい', '空いろのくれよん', '風をあつめて', '暗闇坂むささび変化', 'はいからはくち', 'はいから・びゅーちふる', '夏なんです', '花いちもんめ', 'あしたてんきになあれ', '颱風', '春らんまん', '愛餓を' ]; constructor(props) { super(props); this.state = { list:this.song }; } render() { return <div className="App"> <header className="App-header"> <div className="App-images"> <Img align="left" /> <Img align="center" /> <Img align="rignt" /> </div> <h1>初めてのステート</h1> <h2>はっぴいえんど</h2> <List title="はっぴいえんど(1970)" song={this.song} /> </header> </div> } } class List extends Component { number = 1; render () { let song = this.props.song; return ( <div> <p>{ this.props.title }</p> <ul> {song.map((item) => <Item number={this.number++} value={item} key={this.nuber} /> )} </ul> </div> ); } } class Item extends Component { liStyle = { listStyleType: "none", textAlign: "left" }; render () { return ( <li style={this.liStyle}>{this.props.number}. {this.props.value}</li> ); } } export default App;
最後に
ステート、プロパティ、コンポーネントと制御構造を組み合わせるとより多彩な表現ができそうです。コンポーネントも繰り返し作っていくことでだんだん見慣れてきました♪
さて、ステートの機能をさらに使いこなすためには「Redux」を利用することになりそうです。Vue.jsでやった「Vuex」と同じ位置づけのツールです。次回以降ではそろそろReduxにも取り組んでいく予定です。それではまた!
※参考:Reactを習得するためにやったことまとめ
qiita.com