適当なHooks入門【useEffect前編】


概要

Reactで開発するにあたってHooksちゅう新しい機能を使うので、公式ドキュメントで勉強したことを投稿していこうと思います。

公式ドキュメント

Hooksとは?

state などの React の機能を、クラスを書かずに使えるようになります

つまり関数コンポーネントで従来のクラスのように、Stateの管理やらライフサイクルっぽいことができる機能みたいです。

副作用フックをやってみる

副作用フックとは?

副作用 (effect) フック により、関数コンポーネント内で副作用を実行することができるようになります

ん〜、これだけだとよくわからん。てかヒントの方がわかりやすい!

ヒント

React のライフサイクルに馴染みがある場合は、useEffect フックを componentDidMount と componentDidUpdate と componentWillUnmount がまとまったものだと考えることができます。

つまり関数コンポーネント内でライフサイクルっぽいことができる関数ってことなんですかね?

クリーンアップを必要としない副作用

  1. React が DOM を更新した後で追加のコードを実行したい場合
import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    alert(count)
  });

  return (
    <div>
      <p>clicked {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

上記のコードではボタンをクリックするとcountが更新されuseEffectが呼ばれアラートが表示されます。

useEffect内の処理は初回のレンダー時および毎回の更新時に呼ばれるため、ライフサイクルで言う所の「componentDidMount」や「componentDidUpdate」と同じような動作となります。

クリーンアップを有する副作用

  1. 購読をセットアップしたい場合
import React, { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  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);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

※ 公式ドキュメントの例

すごい適当に言うと、「componentWillUnmount」内でやるような処理はuseEffect内で関数(上記の場合cleanup関数)を返せば同じようなことができるみたいです。

ざっくりまとめ

  1. useEffectを使うと関数コンポーネント内でライフサイクルっぽいことができるで
  2. 「componentDidMount」「componentDidUpdate」でやる処理はuseEffect内に書くんやで
  3. 「componentWillUnmount」でやる処理はuseEffect内でやりたい処理を書いた関数を返してや

おわりに

一見簡単なように見えましたが、実際に既存のクラスコンポーネントをfooks化した際はハマるところが多かったです。
でもとりあえずは、まとめのような感じの理解でいいのかもしれない。。。