【React】フロント初心者が公式チュートリアルをやってみた

こんにちは、久しぶりの記事投稿です。
転職先でReactを使っていて、話に何もついていけずに焦ったので、何かいい勉強材料ないかなと調べていたら公式のチュートリアルがあるのを発見しました。

せっかくなので、チュートリアルをやりつつ困ったポイントなどを補足して記事にしてみました。
自分と同じくフロントはちょっと苦手・・・って方に参考にしてもらえればと思います。

# 公式チュートリアルページ

こちらのページが公式のチュートリアルになっています。
手っ取り早く習得したかったので、日本語版のサイトをみながら勉強しました。

https://ja.reactjs.org/tutorial/tutorial.html

翻訳した日本語独特の言い回しがたまに気になりますが、概ねストレスなく読み進められます。

# 環境構築

ブラウザでコードを書いてリアルタイムで表示してくれる便利なcodepen.ioを使えば環境構築をせずともチュートリアルを受けられます。
自分は環境構築も含めて勉強したかったのでわざわざ環境を構築しました。
ただ、エディタ使った方が自動補完など効くので、環境構築するのをおすすめします。

## Node.jsのインストール

インストールの方法は色々ありますが、ここではnodebrewを用いた方法を紹介します(mac向けです)。

### homebrewのインストール

https://brew.sh/index

上記サイトのInstall Homebrewにあるコマンドをターミナルにコピペします。
ターミナルを再起動して `brew -v`でバージョンが表示されればOKです。

### nodebrewのインストール

以下打つだけでOKです。

```zsh
brew install nodebrew
```

`nodebrew -v`でコマンドが返って来ればOKです。

### Node.jsのインストール、有効化

バージョンへのこだわりがなければ安定板をインストールして有効化しましょう。

```zsh
nodebrew setup
nodebrew install-binary stable
nodebrew use latest
```

### 環境変数設定

このままでは有効化はできましたが、ターミナルから`node -v`など打っても反応しない状態です。
なので、それを認識してあげるように環境変数を設定します。

```zsh
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zprofile
```

ここでターミナルを再起動すると、`node -v`でバージョンが返ってくるはずです。

### いよいよ、Reactの環境構築

あとは、こちらを手順通りやっていけばOKです。

https://ja.reactjs.org/tutorial/tutorial.html#setup-option-2-local-development-environment

ちょっと面倒な方のためにリポジトリに上げておきました。

https://github.com/okaponta/react-tutorial

以下コマンド打てばOKです。

```zsh
git clone https://github.com/okaponta/react-tutorial.git ./react-tutorial
cd react-tutorial
npm install
npm start
```

# いよいよ、チュートリアル

先ほど、`npm start`を打ったと思うのですが、
そうするとエディタから編集して保存をすると自動でコンパイルしてくれます。
コードを保存して、ブラウザで更新すれば反映されているはずです。

チュートリアルのタイトルと対応して気づいた点や詰まったポイントを書いていきます。
公式チュートリアルページと対応させながら見ていただければと思います。

公式チュートリアルの各章ごとにコミットを分けているので、見合わせながら参考にしていただければと思います。

## データをProps経由で渡す

コードはこのように貼っていきます。

https://github.com/okaponta/react-tutorial/commit/8c3e904ab462f672ae890a6b291d369ad68c0bc4

### この章の気づきや、学びや、ぼやきなどを箇条書きで書いていきます。
 - 親コンポーネントから子コンポーネントに値を渡す時はpropsって名前で渡ってくる
 - ここはReactコンポーネントのお決まりで覚えるものなのかな

## インタラクティブなコンポーネントを作る

https://github.com/okaponta/react-tutorial/commit/274575c1ffef07ff379aea7ac87196706c0cacb2

 - onClickのコールバック関数も一緒にjsx形式(?)で書ける。
 - stateという新しい概念が出てきた。javaでいうところのpropsが引数、stateがフィールド変数みたいなイメージ。
 - setStateはReactコンポーネントのメソッドでこれからよく使いそうな気がする。

## State のリフトアップ

https://github.com/okaponta/react-tutorial/commit/2df083e6c67a452a579583f3e949aa4edc4561fb

 - Stateのリフトアップもほどほどにしないと親コンポーネントが全てのpropsを持つみたいな構造になりそうで怖いなぁと思った。
 - 関数が定義されていないなどの場合に画面でエラーをわかりやすく表示してくれるのは好感度高い。
 - `onClick={() => this.props.onClick()}`の部分、`onClick={this.props.onClick}`でも動いた。

## イミュータビリティは何故重要なのか

 - フロント側の言語はどこでも簡単にアクセスできて書き換え可能だったりするので、やっぱりイミュータブルにした方が壊れにくいんだよなぁと改めて実感。。
 - この章をわざわざ作成した開発者の思いを感じました (自分も以前フロント開発した時にどこがどう値を更新しているか分からずなぜ動いているのか分からないみたいな状況になったこともあり・・・)。

## 関数コンポーネント

https://github.com/okaponta/react-tutorial/commit/2f340c9b2b351fef2979e6f85e6c8606365d7c88

 - `render()`だけを持つようなReactコンポーネントは関数コンポーネントとして簡略化して書ける。これは知ってないとはじめてみた時に混乱しそう。
 - 末端のコンポーネントは基本的には`props`を親からもらって描画するという仕組みになりそうだから簡単なやつらはこの関数コンポーネントで書けるようになりそう、だと予想。

## 手番の処理

https://github.com/okaponta/react-tutorial/commit/f8fc8d6bc7a473ebfcc5bb0f0858317d0eeda519

 - ここは、`state`に値を追加するくらいだったので、特に新たなことはなかった気がする。

## ゲーム勝者の判定

https://github.com/okaponta/react-tutorial/commit/54eb00edd6d471f6374e91aa601d802e9957ebca

ヘルパー関数が最初よく分からなかったので、コメントいれて補足してみました。

```js
function calculateWinner(squares) { // 引数は配列
  const lines = [ // 勝ってる場合の石の並び
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) { // 勝ちパターンのぶんだけループ
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      // if(squares[a])だと、aが未入力の場合にfalseになる。
      // ので、この条件はsquares[a]に値が入ってて、かつsquares[b]とsquares[c]も同じ場合にtrue
      return squares[a];  // 勝者を返す
    }
  }
  return null;  // 未決着の場合はnull
}
```

 - 手順通りやってくだけでマルバツゲームが完成した・・・
   - TDDのBowling Game Kataみを感じた
 - `state`で状態を共有して勝手に描画してくれるのが構造をシンプルにしてくれてる気がする。

## Stateのリフトアップ、再び

https://github.com/okaponta/react-tutorial/commit/ccbc6c728b12f2a90fe44d991dea82adb5ed7fc0

結構この章は激しく構造を変えていて、理解するのに時間かかりました。

 - `xIsNext`はなんでリフトアップするの？
   - 履歴を管理するときに盤面と一緒に次どの手番かを記憶したいから
 - `handleClick`ももともと現在の状態に操作していたのを履歴に追加するという操作に結構変わったので、処理も少し複雑になった
 - 手順と異なり最初に`onClick`を修正したため、しばらくコンパイルエラーで描画できない時間があった。手順通りやればとりあえず描画できる状態は続くのでリファクタの順番も大切だなと実感。きちんと手順通りやるのが大事だなと。。

## 過去の着手の表示

https://github.com/okaponta/react-tutorial/commit/4de6b3c43b22edbc23f784d2970f7f63790dd3dc

自分のjsなどの知識が足らずにここも理解に時間かかりました。以下メモです。

```jsx
const moves = history.map((step, move) => { // mapの第1引数は配列要素(squares)、第2引数はインデックス
  const desc = move ? // moveが0、つまりまだ手を打っていないとき、falseになる
    'Go to move #' + move :
    'Go to game start';
  return ( //<ol>はrender()内で宣言してる
    <li>
      <button onClick={() => this.jumpTo(move)}>{desc}</button>
    </li>
  );
});
```

## keyを選ぶ

 - Reactのリストにはkey要素って特別な概念があって、それをもって新規リストかどうかを判別するらしい。
 - 正直あんまりピンときてないので、Reactのリストのときkeyについて気をつけると覚えておく。

## タイムトラベルの実装

https://github.com/okaponta/react-tutorial/commit/6ff0e6c0a289096829bf27be03efc9f7429acf93

 - あれ、`jumpTo`の中で`history`をいじらなくていいのかな？
   - 4こめにjumpしたら5こめと6こめの`history`が維持されちゃう
   - 後で`jumpTo`の中でやってた。
   - 戻る手番を間違えたときのことを考えると、こっちのしようのがよさそう。
 - `slice(first,end)`で配列の要素の切り取りができる

## 完走した感想

 - 環境構築が簡単！！
    - つよつよエンジニアじゃなくても手軽に使えるのはやっぱり初心者には助かりますね。
    - あと、google拡張機能のやつすごい。こんなの欲しかった。
 - ほどよい難易度
    - 簡単すぎず、難しすぎず。後半にいくほど行間があいてきて自分で考える必要もでてくるって感じです。
    - プログラム書くの初めてです！って方にはちょっと難易度高めな気はする。
    - 動くのでたのしい！！！
 - とりあえずとっかかりとして`props`、`store`、`render`あたりを体感できたのでOKかなって気はします。