useEffectで値の比較
React HooksのuseEffect
でoldValues
とnewValues
を比較する方法
解説
React HooksのuseEffect
は、コンポーネントのレンダリング後に副作用を実行するための機能です。このとき、依存性配列(dependency array)を使用して、useEffect
がいつ再実行されるかを制御することができます。
useEffect
の依存性配列に値を追加すると、その値が変更されたときにuseEffect
が再実行されます。しかし、場合によっては、値が変更されたときでも、useEffect
を再実行する必要がないことがあります。このような状況では、oldValues
とnewValues
を比較して、必要に応じてuseEffect
を実行するかどうかを判断することができます。
例
import { useEffect, useState } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const [inputValue, setInputValue] = useState('');
useEffect(() => {
// countが変更されたときのみ実行
if (count !== oldCount) {
console.log('count has changed:', count);
}
}, [count, oldCount]);
useEffect(() => {
// inputValueが変更されたときのみ実行
if (inputValue !== oldInputValue) {
console.log('inputValue has changed:', inputValue);
}
}, [inputValue, oldInputValue]);
// ...
}
この例では、oldCount
とoldInputValue
という変数を定義して、前回の値を保持しています。useEffect
の依存性配列にこれらの変数と現在の値(count
とinputValue
)を追加することで、値が変更されたときにのみuseEffect
が再実行されるようにしています。
ポイント
oldValues
とnewValues
を適切に管理することで、パフォーマンスを向上させることができます。- 値が変更されたときでも、必要に応じて
useEffect
を再実行するかどうかを判断するために、oldValues
とnewValues
を比較することができます。 - 依存性配列には、
useEffect
が再実行されるべき値を指定します。
React HooksのuseEffect
で値を比較する例
日本語訳
React HooksのuseEffect
で値を比較するコード例を説明します。
例1: 値が変更されたときにのみ副作用を実行する
import { useEffect, useState } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const [inputValue, setInputValue] = useState('');
useEffect(() => {
// countが変更されたときのみ実行
if (count !== oldCount) {
console.log('count has changed:', count);
}
}, [count, oldCount]);
useEffect(() => {
// inputValueが変更されたときのみ実行
if (inputValue !== oldInputValue) {
console.log('inputValue has changed:', inputValue);
}
}, [inputValue, oldInputValue]);
// ...
}
例2: 値が変更されたかどうかを判定して条件分岐を行う
import { useEffect, useState } from 'react';
function MyComponent() {
const [value, setValue] = useState(0);
useEffect(() => {
if (value !== oldValue) {
if (value > 10) {
console.log('value is greater than 10');
} else {
console.log('value is less than or equal to 10');
}
}
}, [value, oldValue]);
// ...
}
この例では、value
が変更されたかどうかを判定して、条件分岐を実行しています。値が変更された場合にのみ、条件分岐が実行されます。
例3: 値が変更されたときにのみAPI呼び出しを行う
import { useEffect, useState } from 'react';
function MyComponent() {
const [searchQuery, setSearchQuery] = useState('');
const [results, setResults] = useState([]);
useEffect(() => {
if (searchQuery !== oldSearchQuery) {
// API呼び出し
fetch(`/api/search?query=${searchQuery}`)
.then(response => response.json())
.then(data => setResults(data));
}
}, [searchQuery, oldSearchQuery]);
// ...
}
この例では、searchQuery
が変更されたときにのみAPI呼び出しを行い、検索結果を更新しています。
useRef
フックは、コンポーネントのレンダリング間で値を保持することができます。これを利用して、前回の値を保存し、現在の値と比較することができます。
import { useEffect, useState, useRef } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const prevCountRef = useRef(null);
useEffect(() => {
if (prevCountRef.current !== null) {
console.log('count has changed from', prevCountRef.current, 'to', count);
}
prevCountRef.current = count;
}, [count]);
// ...
}
この方法では、prevCountRef
というuseRef
フックを使用して、前回の値を保存しています。useEffect
の依存性配列にcount
を追加することで、count
が変更されたときにのみuseEffect
が再実行され、前回の値と比較することができます。
useCallbackフックを使用する
useCallback
フックは、関数をメモ化することができます。これにより、関数が再作成されるのを防ぎ、パフォーマンスを向上させることができます。
import { useEffect, useState, useCallback } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const [inputValue, setInputValue] = useState('');
const handleCountChange = useCallback((newCount) => {
setCount(newCount);
}, []);
useEffect(() => {
if (count !== oldCount) {
console.log('count has changed:', count);
}
}, [count, oldCount]);
// ...
}
この方法では、handleCountChange
という関数をuseCallback
フックでメモ化しています。これにより、関数が再作成されるのを防ぎ、useEffect
の依存性配列にhandleCountChange
を追加しても、useEffect
が不要に再実行されるのを防ぐことができます。
カスタムフックを使用する
カスタムフックを作成して、値の比較と副作用の実行をカプセル化することができます。
import { useEffect, useState, useRef } from 'react';
function useCompare(value, callback) {
const prevValueRef = useRef();
useEffect(() => {
if (prevValueRef.current !== null && value !== prevValueRef.current) {
callback(value, prevValueRef.current);
}
prevValueRef.current = value;
}, [value, callback]);
}
function MyComponent() {
const [count, setCount] = useState(0);
useCompare(count, (newCount, oldCount) => {
console.log('count has changed from', oldCount, 'to', newCount);
});
// ...
}
この方法では、useCompare
というカスタムフックを作成して、値の比較と副作用の実行をカプセル化しています。これにより、コードをよりモジュール化し、再利用しやすくなります。
reactjs react-hooks