$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

React Hooksを学んだ

React学習メモ - $shibayu36->blog;にてReactを学習したので、続いてReact Hooksを学んだ。Reactのドキュメントはわかりやすくて良い...

以下メモ書き。

全体を通して感じたこと

  • 基本React Hooksの方が非常に見通しが良くなりそうだけど、今後クラス型コンポーネントを使う意味って何かあるのかな?
  • useEffectの副作用関数とクリーンナップ関数は毎回呼ばれるので、パフォーマンス問題に気をつけよう。基本は第二引数指定し、関係する変数の更新があったときのみ実行するようにしたら良い
  • ルールがいくつかあるので、linterは必ず使ったほうが良さそう

各ドキュメントごとのメモ

https://ja.reactjs.org/docs/hooks-overview.html

  • useStateはいままでsetStateで使っていたようなものを、useEffectは今までcomponentDidMountやcomponentDidUpdate、componentWillUnmountで処理していた内容を書く
  • hookは関数のトップレベルで
  • hookの適切な利用のためのlinterもある
  • useStateなどを、用いてカスタムフックを定義可能。ただし状態は別のものが利用される

https://ja.reactjs.org/docs/hooks-effect.html

  • useEffectの中の副作用関数は毎回のレンダー後に呼ばれると考えたら良い
  • setEffectでクリーンナップ処理を関数を返せば、毎回のレンダー後に前回の副作用をクリーンナップしてくれる。なぜコンポーネントアンマウント時だけでなく毎回のレンダー後なのかは、副作用処理で参照しているpropなどのデータがコンポーネント表示中に変更されてしまったときに、バグってしまうため
  • useEffectの第二引数に配列を渡すことで、それらの値が変わってない時は副作用を起こさないようにできる
    • もしマウント時とアンマウント時のみに実行したいなら、第二引数を空配列にすると良い
  • lintあるの便利〜
    • eslint-plugin-react-hooks パッケージの exhaustive-deps ルールを有効にすることをお勧めします。これは依存の配列が正しく記述されていない場合に警告し、修正を提案します。

  • 以下サンプルの例
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // Specify how to clean up after this effect:
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

フックのルール – React

  • eslint-plugin-react-hooksを使っておいたらルール守れる
  • サンプルにある以下の設定で良さげ
{
  “plugins”: [
    // …
    “react-hooks”
  ],
  “rules”: {
    // …
    “react-hooks/rules-of-hooks”: “error”, // Checks rules of Hooks
    “react-hooks/exhaustive-deps”: “warn” // Checks effect dependencies
  }
}
  • useStateの呼び出しと、stateの対応関係を知るのはフックが呼ばれる順番に依存するため、条件文のなかでuseStateを使うと死ぬ
    • 条件があるならuseStateなどの中に入れれば良い

カスタムフックの作成 – React

  • フックのルールの自動チェックのためにも、カスタムフックは必ずuseで始めよう