See the Elephant

1992生まれのプログラマが書くエンジニアブログ

【React】useEffectってなんだろ

useEffectってなんだろ

仕事でreactを読んでいた時に出てきた記法

useEffect(()=>{}, [])

副作用フックと呼ばれるらしい。広くはhooksと呼ばれるっぽいね

ja.reactjs.org

副作用フックは何かっていうと「コンポーネントの状態が変わった時にフックされる処理」って感じのイメージをしている。

useEffect(()=>{}, [])

これは何を表しているかというと

  • 第1引数 ()=>{} : フック時に実行される処理
  • 第2引数 [] : フックの監視対象とするstate項目

第2引数に何も指定されない場合は最初の一回だけ処理されるらしい。

ここまで理解すると以下のコードが読める。

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]);

count に副作用、つまり変更がある度に document.title が更新される。

react dom life cycle

公式曰く

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

ふむ〜、componentDidMount とかはreactのdom生成ライフサイクルっぽいね。

素晴らしい図を書いている人がいたので引用

GitHub - iktakahiro/react-component-lifecycle-diagram

https://github.com/iktakahiro/react-component-lifecycle-diagram/raw/master/react-v16.2/react-component-lifecycle.png

  • componentDidMount: componentの描画を終えた
  • componentDidUpdate: componentのupdate描画を終えた
  • componentWillUnmount: componentがアンマウントされようとしている

多分こんなところだろう。いまはこれらを使うのは非推奨らしい。

簡単に無限ループを産むことができるから、と先輩から聞いた。

useEffectでreact dom life cycle も表現できる

qiita.com

から引用

componentDidMount

useEffect(() => {
    alert("最初のマウント時のみ実行される");
  }, []);

わかりやすいね。初期化処理に使われる。

componentDidUpdate

  useEffect(() => {
    alert("初回マウント時とstate更新後に毎回実行される");
  },[state]);

副作用が起きたら再描画。

これもわかりやすい。

あまりコンポーネントのライフサイクルを感じさせないのも個人的にはgood。

componentWillUnmount

  useEffect(() => {
    return () => {
      alert("アンマウント時のみ実行される");
    };
  }, []);

これはあんまり直感的ではないなー

高階関数にするとunmount相当になるらしい

なんでなんだろう。今回はそういうものって理解で収めておこう

何が嬉しいの?

一言で言うと、監視対象ごとに処理を切り分けられる からだと思う。

useEffect の第2引数で初期化や監視対象をコントロールできる。

// 初期化
useEffect(() => {
    document.user.name = "";
    document.user.email = "";
  }, []);


// ユーザ名
useEffect(() => {
    document.username = `You name is  ${props.user.name}`;
  }, [props.user.name]);

// email, tel
useEffect(() => {
    document.user.email = props.user.email;
    document.user.tel = props.user.tel;
  }, [props.user.email, props.user.tel]);

雑な例だが、監視対象ごとに処理を変更できる。

もう少し複雑な例では、入力されたデータに基づき加工したデータを表示したい場合は useEffectを利用すると対象がわかりやすく直感的に記述できる。

useEffect の嬉しさはそこだろう。

今日はここまで