masalibの日記

システム開発、運用と猫の写真ブログです

React hooksの入門(useEffect)

React hooksの基礎中の基礎は勉強したけど、その他の機能も知らないといけないと思ったので勉強しています

useEffectとは

useEffectはアンマウント(初期読み込み)、状態を変更するなど、 取り付けによる副作用(DOMの書き換え、変数代入、API通信など)を処理するのに最適です

クラスコンポーネントでのライフサイクルメソッドに当たります。

  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount

クラスコンポーネントは、すべての副作用がライフサイクルメソッドで処理されます。 これにより、単純な副作用を簡単に定義できますが、 クリーンアップ(初期化)する必要のある複数の副作用を定義し始めると、 それらすべてをいくつかのライフサイクルメソッドに詰め込むと非常に複雑になる可能性が高いです。

useEffectの例

useEffect(() => {
  console.log('Hello,useEffect')
})

コンポーネントのすべてのレンダリングで実行されるようになりました。 つまりコンポーネントが最初にマウント(初期表示)されたとき、propsが変更されたとき、 またはstateが変更されたときです。

すべてのレンダリング処理で実行される処理なんて・・・ないですよね。 初期表示のみ、特定のstate(変数)が変更された時に実行されるのが普通です

初期表示のuseEffectの例

useEffect(() => {
  console.log('初期表示のみ実行されます')
}, [])

特定のstate(変数)が変更された時のuseEffectの例

useEffect(() => {
  console.log('stateの内容が変更になった時')
}, [state])

特定の変数が変更された時にAPIを叩くという事もできます

import React, { useState, useEffect } from "react";

export default function App() {
  const [resourceType, setResourceType] = useState("posts");
  const [items, setItems] = useState([]);

  useEffect(() => {
    console.log("render resourceType(対象が書き換わった)");
    fetch(`https://jsonplaceholder.typicode.com/${resourceType}/`)
      .then((response) => response.json())
      .then((json) => setItems(json));

  }, [resourceType]);

  return (
    <>
      <button onClick={() => setResourceType("posts")}>posts</button>
      <button onClick={() => setResourceType("users")}>users</button>
      <button onClick={() => setResourceType("comments")}>comments</button>

      <h1>{resourceType}</h1>
      {items.map((item) => {
        return <pre key={item.id}>{JSON.stringify(item)}</pre>;
      })}
    </>
  );
}

ボタンを押されるとsetResourceTypeでresourceTypeの内容が変わります。変わるとuseEffectが動きAPIがたたかれます。そしてその内容がは反映されます

  useEffect(() => {
    console.log("render resourceType(対象が書き換わった)");
    fetch(`https://jsonplaceholder.typicode.com/${resourceType}/`)
      .then((response) => response.json())
      .then((json) => setItems(json));

  }, [resourceType]);

useEffectの副作用のクリーンアップ

useEffect(() => {
  console.log('task 1')

  return () => {
    console.log('clean up')
  }

  console.log('task 2')

})

コンソールログ上では以下のようになります

clean up
task 1
task 2

Windowの幅が変更時に処理を実行したい場合

  //windowの幅を変更時の処理
  const handleResize = () => {
    setWindowWidth(window.innerWidth);
    console.log(`resize:${window.innerWidth}`);
  };

  useEffect(() => {
    console.log(
      "onMount(初期読み込み時にも読み込まれるがイベントがないのでresizeされない)"
    );
    window.addEventListener("resize", handleResize);
  }, []);

windowが変更時に処理を実行する事ができます

動かして確認したい人は・・・

codesandboxで作ってみました

sourceをみたい人は上記のcodesandboxの左のバーを右にずらせば見ることができます

f:id:masalib:20201110164117g:plain

ソースだけみたい人は

https://github.com/masalib/Learn-React-useEffect

参考URL

https://qiita.com/seira/items/e62890f11e91f6b9653f https://blog.webdevsimplified.com/2020-04/use-effect/ https://youtu.be/0ZJgIjIuY7U