はじめに
私自身の復習兼、備忘録的な意味もあり、複数回の記事に渡って 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 のマスで実装していきます。
今回の目的
3x3 のマスで構成された盤面を作成していきます。いよいよコーディングを開始です。
開発
次のページで、前回のソースファイルを確認できます。
- 前回の内容はコチラから!
マスの作成
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」が記されたマスが表示されます。
このままでは、見た目が味気ないので 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 を読み込みます。
import "./styles.css";
export default function Square() {
return (
<button className="square">X</button>
);
}
これで styles.css のスタイルが適用されます。
盤面の作成
次に複数のマスを表示して、盤面の作成していきましょう。
2つのマスを表示する
まずは、2つのマスを表示させます。
import "./styles.css";
export default function Square() {
return (
<>
<button className="square">X</button>
<button className="square">X</button>
</>
);
}
フラグメント <>
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つ記述していきましょう。
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行に表示されます。
そこで、<button>
要素を <div>
要素で3個ずつまとめましょう。各 <div>
要素には同じ className
を指定しましょう。
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>
要素の後に関するスタイリングができます。
.board-row::after {
clear: both;
content: "";
display: table;
}
これで 3x3 の盤面ができました。
コンポーネントの分解
ここで App.js のプログラムを振り返ると、Square
コンポーネントで複数のマスを直接的にコーディングすることで、盤面が作成されていますね。
これを次のような構成に分解してみます。
-
Board
コンポーネント (親コンポーネント)- 盤上を構成する要素
- 複数の
Square
コンポーネントを呼ぶ
-
Square
コンポーネント (子コンポーネント)- マスを構成する要素
- 呼ばれるときには、マス内に表示する文字を受け取る
App.js のプログラムを次のように変更しましょう。
-
Board
コンポーネントを実装する- 「
export default function Square()
」のリネーム
コンポーネント名Square()
をBoard()
に変更する -
<button className="square">X</button>
を<Square />
に変更する
- 「
- 新たに
Square
コンポーネントを実装する- プロパティ(引数)として
value
を加える -
<button>
要素でvalue
プロパティの値を表示させる
- プロパティ(引数)として
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>
要素に表示する
これを省略するとどうなるのか、試してみましょう。
function Square(value) {
return <button className="square">value</button>;
}
結果、次のように value
が文字列として認識されます。これは HTML での <button>
要素 と同様の結果であることが確認できます。
おわりに
今回は、Square
コンポーネントと Borad
コンポーネントで盤面を作成していきました。次のページに現段階のソースファイルを示します。
次回は盤面上にあるマスに対してマウスによるインタラクションを実装していきます!