サーバレス練習帳

着眼大局着手小局

REACTで〇×ゲームのチュートリアル!

ACM発行の待ち時間が長そうなので、やってみようかな。
ja.reactjs.org

【1】はじめに ~ 〇×ゲームを始めよう!

自分はゲームを作りたいのではないから、と飛ばしたくなるかもしれませんが、是非目を通してみてください。

・・・とありますが、実はゲームにも興味があります。
ちなみに、私の環境はWindows10です。node.jsインストール済。

まずは、完成版の〇×ゲームを見てみます。
https://codepen.io/gaearon/pen/gWWZgR?editors=0010
英語でtic-tac-toeというそうです。
いつか、バックエンドに機械学習を埋め込んでみたいですね。(それはさておき)

【2】環境準備
さて、最初のコードです。
https://codepen.io/gaearon/pen/oWWQNa

私は自分のローカルで動かしたいので、ローカルにコピーすることにします。

C:\node> npx create-react-app react01
C:\node>cd react01\src
C:\node\react01\src>del *
C:\node\react01\src\*、よろしいですか (Y/N)? y

そして、前述の〇×ゲームの最初のコードが載っているサイトからsrcフォルダに3つのファイルを作成します。

C:\node\react01\src>dir
 C:\node\react01\src のディレクトリ

2020/05/06  12:54    <DIR>          .
2020/05/06  12:54    <DIR>          ..
2020/05/06  12:40               639 index.css
2020/05/06  12:40             1,162 index.html
2020/05/06  12:41             1,257 index.js

index.jsには先頭3行に次のimportを追記します。

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

ここで、npm startを実行して、http://localhost:3000 を開くと・・・
f:id:urbanplanner:20200506130027p:plain

さぁ、どんどん行こう!

【3】Reactとは?

React はユーザインターフェイスを構築するための、宣言型で効率的で柔軟な JavaScript ライブラリです。複雑な UI を、「コンポーネント」と呼ばれる小さく独立した部品から組み立てることができます。

今、index.js内にはSquareとBoardとGameの3つのクラスがあります。

【4】データを Props 経由で渡す
Propsって、何・・・? 英語辞書によれば「小道具」という意味だそうな。

React では、親から子へと props を渡すことで、アプリ内を情報が流れていきます。

・・・とのこと。きちんと理解できていないかもしれませんが、とりあえずここまでは動きました。

【5】インタラクティブコンポーネントを作る
さて、ここでもアロー関数式が出てきました。少しだけ慣れてきたかな。

      <button className="square" onClick={function() { alert('click'); }}>

↓↓↓

     <button className="square" onClick={() => alert('click')}>

アロー関数式の注意も書かれていました。(再レンダーのたびにアラートとか困る!)

onClick={() => alert('click')} と記載したときに onClick プロパティに渡しているのは関数であることに注意してください。React はクリックされるまでこの関数を実行しません。() => を書くのを忘れて onClick={alert('click')} と書くのはよくある間違いであり、こうするとコンポーネントが再レンダーされるたびにアラートが表示されてしまいます。

次はステートです。

次のステップとして、Square コンポーネントに自分がクリックされたことを「覚えさせ」て、“X” マークでマスを埋めるようにさせます。コンポーネントが何かを「覚える」ためには、state というものを使います。

React コンポーネントはコンストラクタで this.state を設定することで、状態を持つことができるようになります。this.state はそれが定義されているコンポーネント内でプライベートと見なすべきものです。現在の Square の状態を this.state に保存して、マス目がクリックされた時にそれを変更するようにしましょう。

ここで、現時点のSquareクラスです。

class Square extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: null,
    };
  }

  render() {
    return (
      <button
        className="square"
        onClick={() => this.setState({value: 'X'})}
      >
        {this.state.value}
      </button>
    );
  }
}

このアロー関数式のthisって、何を示しているんだっけ?とか、propsとstateが混同してきたとか、色々思うところはあるのだけど、どんどん進みましょう!

【6】ステートのリフトアップ

Board が各 Square に、現時点の state がどうなっているか問い合わせればよいだけでは、と思うかもしれません。React でそれをすることも可能ですが、コードが分かりにくく、より壊れやすく、リファクタリングしづらいものになるのでお勧めしません。ここでのベストの解決策はそうではなく、ゲームの状態を各 Square の代わりに親の Board コンポーネントで保持することです。Board コンポーネントはそれぞれの Square に props を渡すことで、何を表示すべきかを伝えられます。以前にそれぞれの Square に番号を表示させた時と同じです。

この説明を読んで、stateとpropsの使い方のイメージが付いてきました。ステートは上位のクラスで一括管理するのが良さそうですね。

・・・ということで、ここらへんで飽きてしまいました。まぁ、だいたいイメージはついてきました。続きは、また今度。