ReactとFirebaseでアプリケーションを作る①
①では、環境作成と下地作りまでです。
やりたいこと
- Reactのチュートリアルで基礎を学ぶ
- チュートリアルを参考に、一人神経衰弱ゲームを作る
- Firebase Authentication を使ってログイン認証する
- Firebase を使ってデータを管理する
チュートリアルを修正して、一人神経衰弱ゲームを作る
チュートリアルは、「チュートリアル:React の導入」を利用する。
今回、理解するポイントはチュートリアルの通り。
チュートリアルの準備:以下のチュートリアルを進めるにあたっての開始地点です。
概要:コンポーネントや props、state といった基礎概念について学びます。
ゲームを完成させる:React での開発における非常によくある技法について学びます。
チュートリアルの準備
環境を作る
以前作成したDockerのReact環境「DockerにReact環境を構築する」をクローンする。
git clone https://github.com/abiitaka/docker-react.git react-firebase
docker-compose.yml
と init.sh
のプロジェクト名を変更する。
- 変更前:
reactstudy01
→ 変更後:react-firebase
以降は、チュートリアルの不要なファイルを削除するところから進めていく。
Reactのチュートリアルで基礎を学ぶ
三目並べを作る
チュートリアルに従って進めていくと三目並べは完成する。
作ったソースは以下にあります。
三目並べ作成
チュートリアルのポイント
Reactのチュートリアルでは、リフトアップとイミュータビリティについて補足説明をしている。
以下の2点がポイントです。
リフトアップ
複数の子要素からデータを集めたい、または 2 つの子コンポーネントに互いにやりとりさせたいと思った場合は、代わりに親コンポーネント内で共有の state を宣言する必要があります。親コンポーネントは props を使うことで子に情報を返すことができます。こうすることで、子コンポーネントが兄弟同士、あるいは親との間で常に同期されるようになります。
このように state を親コンポーネントにリフトアップ (lift up) することは React コンポーネントのリファクタリングでよくあることですので、この機会に挑戦してみましょう。
また、「state のリフトアップ」にも、まとめられています。
イミュータビリティ
**ミュータブル (mutable) なオブジェクトは中身が直接書き換えられるため、変更があったかどうかの検出が困難です。**ミュータブルなオブジェクト変更の検出のためには、以前のコピーと比較してオブジェクトツリーの全体を走査する必要があります。
**イミュータブルなオブジェクトでの変更の検出はとても簡単です。**参照しているイミュータブルなオブジェクトが前と別のものであれば、変更があったということです。
mutable、immutableの変更検出は、scpとして「shouldComponentUpdate の実際の動作」にまとめられています。
チュートリアルを参考にひとり神経衰弱ゲームを作る
ルール
- 4x3のマス目を作る
- マスに1〜6までの数字のペアを配置する
- 1つ目をクリックすると数字が表示される
- 2つ目をクリックすると数字が表示される
- 表示した2つの数字がペアかどうか判断する
- ペアであれば表示したまま、ペアでなければ表示しない
ソース
class Board extends React.Component {
constructor(props) {
super(props);
const squareCount = 12;
const initGameBoard = this.generateBoard(squareCount);
this.state = {
gameBoard: initGameBoard,
selectBoard: Array(squareCount).fill(null),
history: [{ selectBoard: Array(squareCount).fill(null) }],
previous: null,
isPair: null,
}
}
handleClick(current) {
// 盤表示
const selectBoard = this.state.selectBoard.slice();
selectBoard[current] = this.state.gameBoard[current];
// ペア判定
let isPair = null, previous = null;
if (this.state.previous == null) {
previous = current;
} else {
isPair = this.isPair(selectBoard[this.state.previous], selectBoard[current]);
}
// 履歴
const history = this.state.history.slice();
this.setState({
selectBoard: selectBoard,
history: history.concat([{ selectBoard: selectBoard }]),
previous: previous,
isPair: isPair,
});
}
// 盤のペア組み合わせ生成
generateBoard(squareCount) {
let result = [];
// ペアの数字を生成
for (let i = 1; i <= squareCount / 2; i++) {
result.push(i, i);
}
// シャッフル(Fisher-Yates shufflアルゴリズム)
for (let i = squareCount - 1; i > 0; i--) {
let random = Math.floor(Math.random() * (i + 1));
let tmp = result[i];
result[i] = result[random];
result[random] = tmp;
}
return result;
}
// ペアをチェックする
isPair(previous, current) {
if (previous == null && current == null) {
return false;
} else if (previous === current) {
return true;
} else {
return false;
}
}
renderSquare(i) {
return (
<Square
value={this.state.selectBoard[i]}
onClick={() => this.handleClick(i)}
/>
);
}
render() {
// ペアにならない場合は盤を戻す
if (this.state.isPair === false) {
setTimeout(() => {
const history = this.state.history.slice(0, this.state.history.length - 2);
const selectBoard = history[history.length - 1].selectBoard.slice();
this.setState({
selectBoard: selectBoard,
history: history,
isPair: null,
});
}, 300);
}
return (
<div>
<p>{this.state.selectBoard.indexOf(null) === -1 ? 'ゲーム終了' : ''}</p>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
{this.renderSquare(3)}
</div>
<div className="board-row">
{this.renderSquare(4)}
{this.renderSquare(5)}
{this.renderSquare(6)}
{this.renderSquare(7)}
</div>
<div className="board-row">
{this.renderSquare(8)}
{this.renderSquare(9)}
{this.renderSquare(10)}
{this.renderSquare(11)}
</div>
</div>
);
}
}
作ったソースは以下にあります。
一人神経衰弱ゲーム作成
Firebase Authentication と Firebase は、「ReactとFirebaseでアプリケーションを作る②(準備中)」でまとめます。