TECH I.S.

ReactuseEffect


useEffectフックを使用すると、コンポーネントで副作用を実行できます。

副作用の例としては、データのフェッチ、DOMの直接更新、タイマーなどがあります。

useEffectは、2つの引数を受け入れます。 2 番目の引数はオプションです。 useEffect(<function>, <dependency>)

例としてタイマーを使用してみましょう。

例:

setTimeout()を使用して、最初のレンダリング後の1秒をカウントするには:
import { useState, useEffect } from "react"; import ReactDOM from "react-dom/client"; function Timer() {   const [count, setCount] = useState(0);   useEffect(() => {     setTimeout(() => {       setCount((count) => count + 1);     }, 1000);   });   return <h1>I've rendered {count} times!</h1>; } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<Timer />);

実行例(開発中です。) »

ちょっと待って!!一度だけカウントするはずなのに、カウントし続けます!

useEffectは、すべてのレンダリングで実行されます。つまり、カウントが変化するとレンダリングが発生し別の効果がトリガーされます。

これは私たちが望んでいるものではありません。副作用が発生するタイミングを制御するには、いくつかの方法があります。

配列を受け入れる2番目のパラメータを常に含める必要があります。オプションで、この配列内の useEffectに依存関係を渡すことができます。

1.依存関係が無い場合:

useEffect(() => {   //Runs on every render });

  1. 空の配列:
useEffect(() => {   //Runs only on the first render }, []);

  1. propsまたはstate value:
useEffect(() => {   //Runs on the first render   //And any time any dependency value changes }, [prop, state]);

したがって、この問題を修正するには、最初のレンダリングでのみこの効果を実行しましょう。

例:

最初のレンダリングでのみ効果を実行します。

import { useState, useEffect } from "react"; import ReactDOM from "react-dom/client"; function Timer() {   const [count, setCount] = useState(0);   useEffect(() => {     setTimeout(() => {       setCount((count) => count + 1);     }, 1000);   }, []); // <- add empty brackets here   return <h1>I've rendered {count} times!</h1>; } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<Timer />);

実行例(開発中です。) »

例:

以下は、変数に依存するuseEffectフックの例です。count変数が更新されると、エフェクトが再度実行されます。
import { useState, useEffect } from "react"; import ReactDOM from "react-dom/client"; function Counter() {   const [count, setCount] = useState(0);   const [calculation, setCalculation] = useState(0);   useEffect(() => {     setCalculation(() => count * 2);   }, [count]); // <- add the count variable here   return (     <>       <p>Count: {count}</p>       <button onClick={() => setCount((c) => c + 1)}>+</button>       <p>Calculation: {calculation}</p>     </>   ); } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<Counter />);

実行例(開発中です。) »

複数の依存関係がある場合、それらはuseEffect依存関係配列に含まれなければいけません。


効果のクリーンアップ

一部のエフェクトでは、メモリリークを減らすためにクリーンアップが必要です。

不要になったタイムアウト、サブスクリプション、イベント リスナー、およびその他の効果は破棄する必要があります。

これを行うには、useEffectフックの最後にreturn関数を含めます。

例:

useEffectフックの終了時にタイマーをクリーンアップします。:
import { useState, useEffect } from "react"; import ReactDOM from "react-dom/client"; function Timer() {   const [count, setCount] = useState(0);   useEffect(() => {     let timer = setTimeout(() => {     setCount((count) => count + 1);   }, 1000);   return () => clearTimeout(timer)   }, []);   return <h1>I've rendered {count} times!</h1>; } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<Timer />);

実行例(開発中です。) »

注:タイマーをクリアするには、名前を付ける必要があります。


プログラミング学習を加速させる

プログラミングをプロの講師に教えてもらいませんか。

テックアイエスのプログラミングスクールは初心者も大歓迎です。年齢制限もありません。転職・副業に強く、挫折させない手厚いサポートで稼ぐ力を身につけましょう!

スクールの詳細