Tips
今日の開発Tips(2025-05-31)
不要な再レンダリングを減らし、パフォーマンスを向上させるためのシンプルなテクニックを紹介します。Reactアプリケーションにおいて、`useMemo`と`useCallback`フックを効果的に活用することで、不要な計算や再レンダリングを回避し、よりスムーズなユーザー体験を実現できます。これにより、特に複雑なコンポーネントのパフォーマンスが大幅に向上します。
ReactにおけるuseMemoとuseCallbackの効果的な活用
useMemoとuseCallbackは、Reactのフックで、パフォーマンス最適化に役立ちます。useMemoは高価な計算の結果をキャッシュし、useCallbackは関数をキャッシュすることで、不要な再レンダリングを防ぎます。
useMemoの使い方
useMemoは、計算結果をメモリにキャッシュします。依存関係の配列が変更されない限り、同じ結果を返します。
import React, { useState, useMemo } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
// 高価な計算をここで行うと仮定します。
const expensiveCalculation = useMemo(() => {
console.log('Expensive calculation!');
// 計算処理
let sum = 0;
for (let i = 0; i < 1000000; i++) {
sum += i;
}
return sum;
}, []); // 空配列は、countが変更されない限り再計算しないことを意味します
return (
<div>
<p>Count: {count}</p>
<p>Expensive Calculation Result: {expensiveCalculation}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
useCallbackの使い方
useCallbackは、関数をキャッシュします。依存関係の配列が変更されない限り、同じ関数を返します。これにより、子コンポーネントが不要な再レンダリングを行うことを防ぎます。
import React, { useState, useCallback } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(count + 1);
}, [count]); // countが変更された場合のみ、increment関数を再生成します
return (
<div>
<ChildComponent onIncrement={increment} />
</div>
);
}
function ChildComponent({ onIncrement }) {
return (
<button onClick={onIncrement}>Increment</button>
);
}
注意点
- 依存関係の配列を正しく指定することが重要です。誤った依存関係を指定すると、意図しない再レンダリングが発生する可能性があります。
useMemoとuseCallbackは、パフォーマンス最適化のためのツールであり、すべてのケースで必要というわけではありません。パフォーマンスボトルネックとなっている部分を特定し、必要に応じて使用するようにしましょう。- 過剰な使用はかえってパフォーマンスを低下させる可能性があるので、プロファイリングツールを使って効果を確認することが重要です。
おすすめポイント
- パフォーマンスの改善に直接的に繋がるため、特に複雑な計算や大きなコンポーネントツリーを持つアプリケーションにおいて効果を発揮します。
- コードの可読性を損なうことなく、パフォーマンスを向上させることができるため、保守性も向上します。