はじめに
私自身の復習兼、備忘録的な意味もあり、複数回の記事に渡って React を用いてマルバツゲーム(三目並べ)を開発していきたいと思います。
シリーズの一覧
- React入門1: 環境構築 [オンライン版]
- React入門2: 盤面の作成
- React入門3: インタラクションの実装
- React入門4: リファクタリング [リフトアップ編]
- React入門5: リファクタリング [インタラクション編]
- React入門6: 手番の実装
- React入門7: ゲームの勝利判定
- React入門8: テキストの実装
- React入門9: タイムトラベル(1)
- React入門10: タイムトラベル(2) (今回)
- React入門11: タイムトラベル(3)
目的について
全体の目的
React公式のチュートリアルで公開されているマルバツゲームを 3x3 のマスで実装していきます。
今回の目的
前回の記事では、盤面の状況を記録するために Game コンポーネントを実装し、Board コンポーネントからのリフトアップをしました。今回の記事では、記録した情報を表示していきます。
タイムトラベル(2)
次のページで、前回のソースファイルを確認できます。
- 前回の内容はコチラから!
map() メソッド
ソースコードを編集する前に、map() メソッドについて説明していきます。このメソッドは、各要素に対してアロー => の後ろに記述した処理の結果を配列で返します。処理が複数の文となる場合は、コードブロック(文を波括弧 {} で囲ったもの)で記述します。
map() メソッドは次のような構文になります。
構文1
配列の要素のみを利用したい場合は、次の構文を利用します。仮引数 には 配列 の要素が渡されます。
配列.map((仮引数) => 仮引数ごとに実行する処理)
例えば、次の map() メソッドを実行すると、コンソールに「[2, 3, 4]」と出力されます。これは、[1, 2, 3] という配列が、map() メソッド内の処理で、要素ごとに x + 1 という処理をされたためです。
console.log([1, 2, 3].map((x) => x + 1));
構文2
配列の要素とその要素番号(インデックス)を利用したい場合は、次の構文を利用します。仮引数1 には 配列 の要素、仮引数2 には 仮引数1 の要素番号が渡されます。
配列.map((仮引数1, 仮引数2) => 要素ごとに実行する処理)
例えば、次の map() メソッドを実行すると、コンソールに「[0, 2, 6]」と出力されます。これは、[1, 2, 3] という配列が、map() メソッド内の処理で、要素ごとに x + 1 という処理をされたためです。
console.log([1, 2, 3].map((x, i) => x * i));
過去の手番の表示
JavaScript の map() メソッドを使って、history 配列の要素数だけ、ボタンを表示していきます。
App.js の Game コンポーネントを次のように変更します。
-
moves配列を定義する-
history配列にmap()メソッドで処理をした後の返り値を代入する-
map()メソッドの仮引数は、squaresとmoveとする。 -
history配列の要素数だけ<li>要素で囲まれた<button>要素を表示する - ボタンには
i番目の手番というテキストを表示させる (i: 要素番号)
-
-
- レンダリング内容の変更
-
<Board>コンポーネントを<div>要素で囲む -
<ol>要素でmoves配列の内容を表示する -
<ol>要素も<div>要素で囲む - 全体をフラグメント
<>で囲む
-
export default function Game() {
const [history, setHistory] = useState([Array(9).fill(null)]);
const [xIsNext, setXIsNext] = useState(true);
const currentSquares = history[history.length - 1];
const moves = history.map((squares, move) => (
<li>
<button>{move} 番目の手番</button>
</li>
));
function handlePlay(nextSquares) {
setHistory([...history, nextSquares]);
setXIsNext(!xIsNext);
}
return (
<>
<div>
<Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
</div>
<div>
<ol>{moves}</ol>
</div>
</>
);
}
次に実行結果を示します。手番が交代するごとにボタンが表示されるようになりました。なお、このボタンはイベントを実装していないので、クリックをしても何も実行されません。
おわりに
今回は、タイムトラベルを実装するにあたり、手番を示すボタンを実装していきました。次のページに現段階のソースファイルを示します。
次回は、このボタンをクリックすることで過去の手番に戻れるようにしていきます。
