React Hooks を雑にメモってまとめる vol.1

超訳・React歴史的経緯

  • Class Base ComponentからFunctional Componentへ
  • SFC(Stateless Functional Component) と関数の入れ子(compose)で振る舞いと見た目を決める
  • State管理とRenderingライフサイクルとしてReduxが関数ミルフィーユを支える
  • React本体が振る舞い自体を関数化しちゃえ!からの React Hooks 爆誕

React Hooks API

https://reactjs.org/docs/hooks-reference.html

useState

const [state, setState] = useState(initialState)

  • state: 状態変数
  • setState: 状態を更新する関数
  • initialState: 状態変数の初期値

SFCにState(とそのupdater)を持たせるための関数。SFC + S = FC。 stateの更新を望む振る舞いごとに、updaterを利用した関数を定義してexportしてあげればView側でその関数をbindするだけでよい。

1
2
3
4
5
6
7
8
export const useCount = () => {
const [count, setCount] = React.useState(0);
const add = () => setCount(count + 1);
const reduce = () => setCount(count - 1);
return { value: count, add, reduce };
};

export default useCount;

サンプル

useEffect

useEffect(実行する関数[, 変更を監視するStateの配列])

Rendering完了後に実行したいことを詰め込む。componentDidMountとかcomponentDidUpdate的なやつ。
第二引数にどのSteteの変更に由来したRenderingであるかを限定する配列を指定できる。
第二引数を省略した場合はすべてのStateをしたことになる(いつも動く)。
useStateで初期値をセットしたときにもHookされるので、componentDidMount相当のことができる。

1
2
3
4
5
6
7
8
9
10
11
const [data, setData] = React.useState({ count: 0, message: "initialize" });

// define any functions use `setData`.....


React.useEffect(
() => {
console.log(`now value is ${data.count}`);
},
[data.count]
);

サンプル

useContext

useContext(AnyContext)

プロダクト開発ではまあめったに使わないし、使えるほどの設計パワーが足りないのでほとんど使わなそう(読むことはきっとある)。
createContext で生成したPropsを下位のコンポーネントが受け取る場合、従来はConsumerのrender props引数から受け取っていたが、
useContext の返却値として受け取れるようになった。Contextからattributeを取り出すようなイメージ。

useReducer

const [state, dispatch] = useReducer(reducer, initialArg, init);

  • reducer: reducer。 actionを受け取ってstateを返す関数
  • initialArg: stateの初期値。
  • init: stateを初期化する関数。任意引数で、init(initialArg) の形で実行される。明示的に初期化を実行する場合(Lazy initialization)などに使用する。

useSteteと似たAPIだが、updaterではなくdispatch関数を返す。dispatchで指定したActionはreducerに渡される。
reducerは現在のstateとactionの値をもとに更新後のstateを回答する。dispatchが更新後のStateを適用してViewが更新される。

useState が個々のStateに対してupdaterを関数化するのに対して、dispatchが全体のStateの更新手順(Action)を指定する。
書いてる分にはreduxと大差ない。updaterがreducerに集合してState更新のルーティングが見え、振る舞いの隠蔽とカプセル化ができる。よい。

サンプル

useMemo

const memoizedValue = useMemo(() => func(a, b), [a, b]);

memo化関数。第二引数に指定した値に変化がある場合のみ、第一引数の関数を実行する。
ReactではRenderingの過程に必要な計算処理はRenderingが起きるたびに毎回実行してしまうが、useMemoを使って関数を定義しておけば監視対象となる値が変化した場合のみRendering過程の計算を再実行し、値が変化していない場合は実行せずに前回の値を使用してくれる。すなわち、複数のPropsのうち、計算が必要なPropsが変更された場合のみrendering過程でのコンピューティングを実行するように最適化できる。

サンプル

useCallback

const memoizedCallback = useMemo(() => func(a, b), [a, b]);

useMemoとほぼ同じだが、関数オブジェクトそのものをmemo化する。

サンプル

useMemouseCallback のサンプルの違いは

1
2
- <p>msg</p>
+ <p>msg()</p>

だけ。
関数オブジェクトをmemo化することによって、Propsに与えている関数が再生性されることを抑制するなどができそう。


vol.1では一旦ここまで。次回、useRefなどの あまりつかわなそう 使用頻度の低い、Hooks APIにふれる。