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?

はじめに

私自身の復習兼、備忘録的な意味もあり、複数回の記事に渡って 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 のマスで実装していきます。

今回の目的

3x3 のマスで構成された盤面を作成していきます。いよいよコーディングを開始です。

開発

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

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

マスの作成

App.js に次のコードを記述しましょう。

App.js
export default function Square() {
  return (
      <button className="square">X</button>
  );
}

export default は、App.jsがインポートされたときに実行されるコンポーネント(関数)を示します。ここでは、App.js が index.js にインポートされることで Square コンポーネントが呼び出されます。なお、コンポーネント名はアルファベットの大文字から始まる必要があります。

return 文を見ると、<button> タグが記述されており、一般的な JavaScript と異なった構文となっていますね。このような HTML と JavaScript を混ぜたような文法を JSX といいます。

これでマスに「X」が記されたマスが表示されます。

image.png

このままでは、見た目が味気ないので styles.css でマスの装飾をしていきます。

styles.css
.square {
  background: #fff;
  border: 1px solid #999;
  float: left;
  font-size: 24px;
  font-weight: bold;
  line-height: 34px;
  height: 34px;
  margin-right: -1px;
  margin-top: -1px;
  padding: 0;
  text-align: center;
  width: 34px;
}

装飾を反映させるために、App.js で styles.css を読み込みます。

App.js
import "./styles.css";

export default function Square() {
  return (
      <button className="square">X</button>
  );
}

これで styles.css のスタイルが適用されます。

image.png

盤面の作成

次に複数のマスを表示して、盤面の作成していきましょう。

2つのマスを表示する

まずは、2つのマスを表示させます。

App.js
import "./styles.css";

export default function Square() {
  return (
    <>
      <button className="square">X</button>
      <button className="square">X</button>
    </>
  );
}

動作結果は、次のようにマスが横方向並んで表示されます。
image.png

フラグメント <>

return 文では2つの <button> 要素が <> という空の要素で囲まれていますね。React では、これをフラグメントといい、複数の要素を返す際に利用されます。次のように、フラグメントを欠いて複数要素を返すとエラーが出力されます。

  • プログラム
    return (
      <button className="square">X</button>
      <button className="square">X</button>
    );
    
  • エラー
    /src/App.js: Adjacent JSX elements must be wrapped in an enclosing tag. 
    Did you want a JSX Fragment <>...</>?
    

3x3の盤面を作成する

2つのマスを表示させたときと同様に、return 文内に <button> 要素を9つ記述していきましょう。

App.js
import "./styles.css";

export default function Square() {
  return (
    <>
      <button className="square">X</button>
      <button className="square">X</button>
      <button className="square">X</button>
      <button className="square">X</button>
      <button className="square">X</button>
      <button className="square">X</button>
      <button className="square">X</button>
      <button className="square">X</button>
      <button className="square">X</button>
    </>
  );
}

動作結果は、9つのマスが1行に表示されます。

image.png

そこで、<button> 要素を <div> 要素で3個ずつまとめましょう。各 <div> 要素には同じ className を指定しましょう。

App.js
import "./styles.css";

export default function Square() {
  return (
    <>
      <div className="board-row">
        <button className="square">X</button>
        <button className="square">X</button>
        <button className="square">X</button>
      </div>
      <div className="board-row">
        <button className="square">X</button>
        <button className="square">X</button>
        <button className="square">X</button>
      </div>
      <div className="board-row">
        <button className="square">X</button>
        <button className="square">X</button>
        <button className="square">X</button>
      </div>
    </>
  );
}

<div> 要素ごとを行とするために、styles.css に次を追記しましょう。::after 疑似要素 によって <div> 要素の後に関するスタイリングができます。

styles.css
.board-row::after {
  clear: both;
  content: "";
  display: table;
}

これで 3x3 の盤面ができました。

image.png

コンポーネントの分解

ここで App.js のプログラムを振り返ると、Square コンポーネントで複数のマスを直接的にコーディングすることで、盤面が作成されていますね。

これを次のような構成に分解してみます。

  • Board コンポーネント (親コンポーネント)
    • 盤上を構成する要素
    • 複数の Square コンポーネントを呼ぶ
  • Square コンポーネント (子コンポーネント)
    • マスを構成する要素
    • 呼ばれるときには、マス内に表示する文字を受け取る

コンポーネント化.jpg

App.js のプログラムを次のように変更しましょう。

  • Board コンポーネントを実装する
    • export default function Square()」のリネーム
      コンポーネント名 Square()Board() に変更する
    • <button className="square">X</button><Square /> に変更する
  • 新たに Square コンポーネントを実装する
    • プロパティ(引数)として value を加える
    • <button> 要素で value プロパティの値を表示させる
App.js
import "./styles.css";

function Square({ value }) {
  return <button className="square">{value}</button>;
}

export default function Board() {
  return (
    <>
      <div className="board-row">
        <Square value="X" />
        <Square value="X" />
        <Square value="X" />
      </div>
      <div className="board-row">
        <Square value="X" />
        <Square value="X" />
        <Square value="X" />
      </div>
      <div className="board-row">
        <Square value="X" />
        <Square value="X" />
        <Square value="X" />
      </div>
    </>
  );
}

波括弧 {} の文法的意味

Square コンポーネントを注目すると波括弧 {} が記述されていますね。JSX で JavaScript の構文を利用する際には、この波括弧が必要です。Square コンポーネントでは、次の2つを実現するために {value} が記述されています。

  • Square コンポーネントのプロパティを設定する
  • プロパティの値を <button> 要素に表示する

これを省略するとどうなるのか、試してみましょう。

App.js: Squareコンポーネント
function Square(value) {
  return <button className="square">value</button>;
}

結果、次のように value が文字列として認識されます。これは HTML での <button> 要素 と同様の結果であることが確認できます。

image.png

おわりに

今回は、Square コンポーネントと Borad コンポーネントで盤面を作成していきました。次のページに現段階のソースファイルを示します。

次回は盤面上にあるマスに対してマウスによるインタラクションを実装していきます!

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?