『速習 React』読書メモ

# 概要
React未経験者が今更ながら入門すべく以下の書籍を読み進めた際の読書メモです。
全くのReact未経験から一つ一つ理解しながら読み進めて、所要時間は約12時間でした。
また、2年ほど前の書籍ですが、現在のReactでもほぼ問題なく読めました。
React入門生からReact初心者くらいにはなれた気がします。

# 書籍

- 書籍名：速習 React
- 著者　：山田祥寛
- 発刊日：2018/08/27
- 頁数　：151ページ
- 公式　：https://wings.msn.to/index.php/-/A-03/WGS-JSF-004/

# 環境構築

- 既存のNode.jsの削除
    - [node.jsのアンインストールと再インストール手順メモ - Qiita](https://qiita.com/wagi0716/items/94193a80502f9d81a9e0)

- HomebrewでNode.jsのバージョンを切り替えられるようにする
    - [MacにNode.jsをインストール（anyenv + nodenv編） - Qiita](https://qiita.com/kyosuke5_20/items/eece817eb283fc9d214f)

- Node.jsのインストール
    - ```$ nodenv install 12.16.2```
    - [nodenv のインストール時に default-packages file not found と表示される問題 - Qiita](https://qiita.com/itooww/items/f229e64b7a971fe64e22)

# 読書メモ

## JSX

- JSX：JSの拡張言語で、タグをJSコードの一部として書くための構文
    - JavaScriptそのものではないので、実行時に内部的にJavaScriptにトランスコンパイル（変換）されている
        - JSXを使ってトランスコンパイルするより、トランスパイル後のコードを直接書いた方が良い場面もある

- Reactではテンプレート（見た目）を表すためにJSXを利用する

- JSX自体はreact.element型のオブジェクトなので、JSX式を変数に代入することも可能
    - ```const tag = <h1>Hoge</h1>;```

- JSXに複数の要素を列挙することはできない（そのような場合は```<div>```要素で囲うなどする）
    - ```<React.Fragment>```で囲えば、実際の出力時にはタグを増やすことなく複数の要素を列挙可能

- JSXでは空要素は「/」で終えなければならない
    - ```const tag = <img src={logo} />```

## コンポーネント

- Reactではアプリをコンポーネント（ページを構成するUI部品）という単位で管理する
    - Reactアプリとは基本的に一つ以上のコンポーネントの集合体

- babel.jsを使えばBabel（トランスコンパイラー）をブラウザ上で実行できる
    - ただし結構な負荷がかかるので、本格的なアプリ開発時にはあらかじめビルドしておいた方が良い
    - JSXやES2015以降のコードを利用しない場合はトランスコンパイルは不要

- コンポーネントを経由しない出力も可能だが、再利用性を考慮すると基本的にはコンポーネントを使うべき
    - コンポーネントにはクラスコンポーネントと関数コンポーネントがあるが、どちらかに統一した方がベター
        - 関数コンポーネントはシンプルに表現可能だが、できることに制限がある
        - [関数コンポーネントはクラスとどう違うのか? — Overreacted](https://overreacted.io/ja/how-are-function-components-different-from-classes/)

## Props/State

- prop-typesライブラリを使うと、コンポーネントに渡されたプロパティ値の型チェックを行える

- bindメソッドはJSの標準メソッドで、「関数配下のthisを引数のオブジェクトに紐付けなさい」という意味

- イベントハンドラを記述する際は、JSXでbindするより、コンストラクターでまとめてbindした方が良い

- Stateを使う際は、まず初期値を設定して、更新はsetStateメソッドで行う

- 親コンポーネント→子コンポーネントの情報伝達にはProps、逆の情報伝達にはStateを利用する

- Reactでフォームを扱う場合の手順
    - Stateでフォーム要素の初期値を定義・フォームに紐付け
    - フォーム要素の変更が行われるたび、入力値をStateに反映
    - 入力値が必要になったら、State値を参照する

## ライフサイクルメソッド

- タイマーなどのリソースを初期化する際は、正しくはコンストラクターではなくライフサイクルメソッドを用いる

- ライフサイクル：コンポーネントが生成された後、最終的に文書ツリーから除去され破棄されるまでの流れのこと
    - ライフサイクルの変化に応じて呼び出されるメソッドをライフサイクルメソッドと呼ぶ
        - コンポーネントの表示・破棄のタイミングでアプリ独自の処理を実行することができる

- ライフサイクルの主なフェーズ
    - Mounting：コンポーネントが生成されて文書ツリーに挿入される時
    - Updating：Props/Stateに変更が発生した時
    - Unmounting：コンポーネントが文書ツリーから除去される時
    - Error Handling：ライフサイクルメソッドなどでエラーが発生した時

- 主なライフサイクルメソッド
    - ```constructor(props)```：コンポーネントの初期化時
        - コンポーネントの初期化時に呼び出され、Stateの初期化やイベントハンドラーのthis固定を目的として利用する
    - ```render()```：コンポーネントの描画時
        - コンポーネントクラスで唯一必須のメソッド
        - 戻り値としてReact要素（配列も可）・文字列・数値・ブール値・nullなどを利用できる
        - コンポーネントからの出力がない（処理だけを行う）場合にはnull値を返す
    - ```componentDidMount()・componentWillUnmount()```：文書ツリーへのコンポーネントの追加時・破棄時
        - 前者はコンポーネントが文書ツリーに追加された直後に呼び出される
            - 文書ツリーへのアクセスを要する操作はこのメソッドで実行する
            - コンポーネント内で利用するリソース（タイマーや通信リクエスト）を初期化するのもこのタイミングで行う
            - setStateを呼び出すことも可能だが、可能な限りStateはconstructorで初期化すべき
        - リソースの初期化・破棄をこの2つの組み合わせで行うのが良くあるパターン
    - ```shouldComponentUpdate(nextProps, nextState)```：Props・Stateによる更新時
        - Props・Stateが更新された時、コンポーネントを再描画する前に呼び出される（Mountingフェーズでは呼び出されない）
        - 戻り値としてfalseを返すことで再描画を中断する
        - Props・Stateの更新内容によって再描画が不要となる場合、その判定のために利用する
        - 主にパフォーマンス改善のための用途で、あまり利用する機会は多くない
    - ```componentDidUpdate(prevProps, prevState, snapshot)```：コンポーネントの再描画時
        - Updatingフェーズでコンポーネントが再描画された後に呼び出される（Mountingフェーズでは呼び出されない）
        - 再描画された後の文書ツリーにアクセスしたい場合に利用する

## ルーティング

- ルーティング：リクエストURLに応じて処理を受け渡すコンポーネントを決定する仕組みのこと
    - SPAを実装する上で欠かせない仕組みで、ルーティング機能を提供するモジュールのことをルーターという

- Reactでルーティングする際にはReact Routerライブラリを利用する
    - React Routerには複数のルーターが用意されているので、用途に応じて使い分ける
        - BrowserRouter：ブラウザーのHistory APIでルーティングを利用するためのルーター
            - 直下の要素は1つでなければならないので```<div>```などを配置する
        - HashRouter：ハッシュ形式でパスを管理するルーター
        - MemoryRouter：メモリ上でのみ履歴を管理するルーター
        - NativeRouter：スマホ環境向けのルーター

- 要素```<Route>```を記述する際、component属性の代わりにrender属性を使えば直接出力を生成可能

- ルーティングを用いたページ遷移を行う際は、通常のアンカータグではなく```<Link>```コンポーネントを利用する

- パスの一部をパラメータとして引き渡すにはルートパラメータを用いる
    - ```<Route path="/article/:id" component={MyArticle} />```

- ルーター環境ではthis.props配下に様々なプロパティがある
    - history：historyオブジェクト
    - location：locationオブジェクト
    - match.params：ルートパラメータ
    - match.path：ルートで定義されたパス（例：/article/:id）
        - match.url：リクエストパス（例：/article/3）