0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

初学者でも完走賞をとりたい!!Advent Calendar 2023

Day 12

React入門10: タイムトラベル(2)

Last updated at Posted at 2023-12-11

はじめに

私自身の復習兼、備忘録的な意味もあり、複数回の記事に渡って React を用いてマルバツゲーム(三目並べ)を開発していきたいと思います。

シリーズの一覧

  1. React入門1: 環境構築 [オンライン版]
  2. React入門2: 盤面の作成
  3. React入門3: インタラクションの実装
  4. React入門4: リファクタリング [リフトアップ編]
  5. React入門5: リファクタリング [インタラクション編]
  6. React入門6: 手番の実装
  7. React入門7: ゲームの勝利判定
  8. React入門8: テキストの実装
  9. React入門9: タイムトラベル(1)
  10. React入門10: タイムトラベル(2) (今回)
  11. React入門11: タイムトラベル(3)

目的について

全体の目的

React公式のチュートリアルで公開されているマルバツゲームを 3x3 のマスで実装していきます。

今回の目的

前回の記事では、盤面の状況を記録するために Game コンポーネントを実装し、Board コンポーネントからのリフトアップをしました。今回の記事では、記録した情報を表示していきます。

タイムトラベル(2)

次のページで、前回のソースファイルを確認できます。

  • 前回の内容はコチラから!

map() メソッド

ソースコードを編集する前に、map() メソッドについて説明していきます。このメソッドは、各要素に対してアロー => の後ろに記述した処理の結果を配列で返します。処理が複数の文となる場合は、コードブロック(文を波括弧 {} で囲ったもの)で記述します。

map() メソッドは次のような構文になります。

構文1

配列の要素のみを利用したい場合は、次の構文を利用します。仮引数 には 配列 の要素が渡されます。

map() メソッドの構文1
配列.map((仮引数) => 仮引数ごとに実行する処理)

例えば、次の map() メソッドを実行すると、コンソールに「[2, 3, 4]」と出力されます。これは、[1, 2, 3] という配列が、map() メソッド内の処理で、要素ごとに x + 1 という処理をされたためです。

map() メソッドの使用例1
console.log([1, 2, 3].map((x) => x + 1));

構文2

配列の要素とその要素番号(インデックス)を利用したい場合は、次の構文を利用します。仮引数1 には 配列 の要素、仮引数2 には 仮引数1 の要素番号が渡されます。

map() メソッドの構文2
配列.map((仮引数1, 仮引数2) => 要素ごとに実行する処理)

例えば、次の map() メソッドを実行すると、コンソールに「[0, 2, 6]」と出力されます。これは、[1, 2, 3] という配列が、map() メソッド内の処理で、要素ごとに x + 1 という処理をされたためです。

map() メソッドの使用例2
console.log([1, 2, 3].map((x, i) => x * i));

過去の手番の表示

JavaScript の map() メソッドを使って、history 配列の要素数だけ、ボタンを表示していきます。

App.js の Game コンポーネントを次のように変更します。

  • moves 配列を定義する
    • history 配列に map() メソッドで処理をした後の返り値を代入する
      • map() メソッドの仮引数は、squaresmove とする。
      • history 配列の要素数だけ <li> 要素で囲まれた <button> 要素を表示する
      • ボタンには i番目の手番 というテキストを表示させる (i : 要素番号)
  • レンダリング内容の変更
    • <Board> コンポーネントを <div> 要素で囲む
    • <ol> 要素で moves 配列の内容を表示する
    • <ol> 要素も <div> 要素で囲む
    • 全体をフラグメント <> で囲む
App.js の Game コンポーネント
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>
    </>
  );
}

次に実行結果を示します。手番が交代するごとにボタンが表示されるようになりました。なお、このボタンはイベントを実装していないので、クリックをしても何も実行されません。

output_video.gif

おわりに

今回は、タイムトラベルを実装するにあたり、手番を示すボタンを実装していきました。次のページに現段階のソースファイルを示します。

次回は、このボタンをクリックすることで過去の手番に戻れるようにしていきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?