Reactチュートリアルを弄って遊ぶ Hooks編
引き続きReactチュートリアルで遊んでいく
今回はReact Hooksを使ってクラスコンポーネントを関数コンポーネントにリファクタリングしていく
現在の状態はこんな感じ
対象となる箇所
Square
コンポーネントは既に関数コンポーネントになっているのでやることはない
Board
コンポーネントはクラスコンポーネントだけど、 state
を持っていないのですぐ関数コンポーネント化することができる
Game
コンポーネントは state
を持つクラスコンポーネントなので、こいつが今回のメインターゲットとなる
Boardコンポーネントの関数コンポーネント化
見ての通り state
を持っていない
- 関数コンポーネントは関数としてExportするので、
export const Board = (props) => {〜}
となる - 関数コンポーネントは
render()
を用意する必要はなく、そのコンポーネントで表示すべき内容をreturn
するだけでOK - 親コンポーネントから受け取ったパラメータは
this.props
ではなく、関数の引数として受け取る形になるので、props.XXX
という感じでthis
はなくなる
といった感じで、 state
がなければ超簡単に関数コンポーネント化ができる
(変換したときのコミットはこちら)
Gameコンポーネントの関数コンポーネント化
こいつは state
を持っているので、Hooksを使ってリファクタする必要がある
useState
を使う方法と、 useReducer
を使う方法があるが、ここでは useState
を使った方法で行う
- 基本的な関数コンポーネント化に必要な作業は
Board
コンポーネントの時と同じ↑ constructor
で定義されているthis.state
に着目し、同じ状態を管理できるよう必要な分だけuseState
を使用する(今回は全てのstateを別々に管理するようにしたが、1つのオブジェクトでもOK)this.state
でstateを参照していた箇所を、useState
の戻り値のstate変数で置き換えるthis.setState
でstateの更新をしていた箇所を、useState
の戻り値のstate更新関数で置き換える
Board
コンポーネントの時と比べたら、当然 state
がある分ちょっと面倒なところはあるが、上記ポイントを押さえればそこまでハマりどころはないはず
(変換したときのコミットはこちら)
useReducerを使ったGameコンポーネントのリファクタ
リファクタ前のuseStateで書かれたGameコンポーネントはこんな感じ
Reduxでも名前はおなじみの useReducer
を使った場合のリファクタをやってみる
useState
も useReducer
もコンポーネントの中だけで状態が完結するという点では同じだが違いもある
どちらを使うべきなのかは、公式のuseReducerに説明があるので、自分のアプリではどうなのかを考えるとよい
(けどまぁReducerで書いておくのが無難な気がする)
なお、Reduxはグローバルに状態管理を行うので、コンポーネントを横断するようなステートを管理する場合に導入を検討するとよい
- 初期ステータスを1つのオブジェクトで用意する
useReducer
を使って現在のstateと、それを更新するためのdispatch
を作成するuseState
の変数と更新関数をuseReducer
で作成したstate
とdispatch
で置き換える
ここまでのコードはこんな感じ
最初の状態と比べたらまぁまぁきれいになって、ある程度現場感が出たのではなかろうか