履歴表示
※Reactを学習したい人は「Reactチュートリアル」で学習してみてください。このブログはこのチュートリアルで感じたことや自分のメモを記述していきます。
タイムトラベル機能実装のためコンポーネントBoardからGameへクリック情報などを移動した。次は履歴情報を表示する。Gameのrenderメソッドを次のように変更する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
render() { const history = this.state.history; const current = history[history.length - 1]; const winner = calculateWinner(current.squares); const moves = history.map((step, move) => { const desc = move ? 'Go to move #' + move : 'Go to game start'; return ( <li key={move}> <button onClick={() => this.jumpTo(move)}>{desc}</button> </li> ); }); let status; if (winner) { status = 'Winner: ' + winner; } else { status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O'); } return ( <div className="game"> <div className="game-board"> <Board squares={current.squares} onClick={(i) => this.handleClick(i)} /> </div> <div className="game-info"> <div>{status}</div> <ol>{moves}</ol> </div> </div> ); } |
map命令
ここで注目したいのは6行目から始まるmap命令だ。
6 7 8 9 10 11 12 13 14 15 |
const moves = history.map((step, move) => { const desc = move ? 'Go to move #' + move : 'Go to game start'; return ( <li key={move}> <button onClick={() => this.jumpTo(move)}>{desc}</button> </li> ); }); |
JavaScriptのmap命令は配列を1件ずつ処理しながら新たな配列を作成する命令だ。またまたReactではなくJavaScriptのお勉強になるが、今風の命令らしく面白そうなので少々深堀してみる。
次のコードで動作を確認する。
1 2 3 4 5 6 |
var arr1 = [ 'a','b','c','d','e']; var arr2 = arr1.map((v,i,a) => { console.log(v,i,a); return v; }); console.log(arr2); |
3行目のconsole.logの結果
1 2 3 4 5 |
a 0 (5) ["a", "b", "c", "d", "e"] b 1 (5) ["a", "b", "c", "d", "e"] c 2 (5) ["a", "b", "c", "d", "e"] d 3 (5) ["a", "b", "c", "d", "e"] e 4 (5) ["a", "b", "c", "d", "e"] |
6行目のconsole.logの結果
1 |
(5) ["a", "b", "c", "d", "e"] |
今回はこのmapを利用して履歴の数だけ <li>タグを作成している。
10 11 12 13 14 |
return ( <li key={move}> <button onClick={() => this.jumpTo(move)}>{desc}</button> </li> ); |
今まではfor文などで実現してきたが、これが今風の書き方?なのかもしれない。気のせいか記述するのが楽に感じだ。
keyタグ
Reactは高速描画を実現するためHTMLの変更を検知する必要がある。このため <li>タグに見慣れないkey属性が記述されている。
11 |
<li key={move}> |
動的にリストを作成する場合にはReactが変更を検知しやすいように、key属性に<li>タグ毎にユニークな値を設定しなければいけない。
ここから推測するとkey属性を適切に設定しなければ、リスト内容が変更されない不具合が発生すると思われる。このような不具合は作成側からすると見落としがちになり、やっかいなものだ。
実行する
コンポーネントGameのrenderメソッドを書き換え実行する。
無事に履歴が表示された。さぁ次に進もう!