安全に使えるユースケース
安全に使えるユースケース
Section titled “安全に使えるユースケース”Reactで安全に使えるユースケースと、その理由を詳しく解説します。
適切なクリーンアップ
Section titled “適切なクリーンアップ”useEffectで追加したイベントリスナーやタイマーを、クリーンアップ関数で削除します。
// ✅ 良い例: 適切なクリーンアップfunction Component() { useEffect(() => { const handleScroll = () => { // 処理... };
window.addEventListener('scroll', handleScroll);
// クリーンアップ関数でイベントリスナーを削除 return () => { window.removeEventListener('scroll', handleScroll); }; }, []);
return <div>Component</div>;}なぜ安全か:
- メモリリークの防止: イベントリスナーを明示的に削除し、メモリリークを防止
- 参照の削除: ハンドラーの参照を削除することで、ガベージコレクションが動作
- ライフサイクル管理: コンポーネントのライフサイクルに合わせて管理
メモ化による再レンダリングの最適化
Section titled “メモ化による再レンダリングの最適化”useMemoやuseCallbackを使用して、不要な再レンダリングを防ぎます。
// ✅ 良い例: メモ化による再レンダリングの最適化function Component({ items }: { items: Item[] }) { // 計算結果をメモ化 const filteredItems = useMemo(() => { return items.filter(item => item.active); }, [items]);
// コールバック関数をメモ化 const handleClick = useCallback((id: number) => { console.log('Clicked:', id); }, []);
return ( <div> {filteredItems.map(item => ( <ChildComponent key={item.id} item={item} onClick={handleClick} /> ))} </div> );}
// 子コンポーネントもメモ化const ChildComponent = React.memo(({ item, onClick }: { item: Item; onClick: (id: number) => void }) => { return <div onClick={() => onClick(item.id)}>{item.text}</div>;});なぜ安全か:
- 再レンダリングの削減: 不要な再レンダリングを防ぎ、パフォーマンスを向上
- メモリ使用量の削減: 再レンダリングが削減され、メモリ使用量が削減
- パフォーマンスの向上: レンダリングパフォーマンスが向上
仮想スクロールによるDOMノード数の制限
Section titled “仮想スクロールによるDOMノード数の制限”大量のデータを表示する場合、仮想スクロールを使用してDOMノード数を制限します。
// ✅ 良い例: 仮想スクロールによるDOMノード数の制限import { useVirtualizer } from '@tanstack/react-virtual';
function VirtualList({ items }: { items: Item[] }) { const parentRef = useRef<HTMLDivElement>(null);
const virtualizer = useVirtualizer({ count: items.length, getScrollElement: () => parentRef.current, estimateSize: () => 50, overscan: 5, // 表示範囲の前後に5個ずつ余分にレンダリング(スクロール時のちらつき防止) });
return ( <div ref={parentRef} style={{ height: '500px', overflow: 'auto' }}> <div style={{ height: `${virtualizer.getTotalSize()}px`, width: '100%', position: 'relative', }} > {virtualizer.getVirtualItems().map(virtualItem => ( <div key={virtualItem.key} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: `${virtualItem.size}px`, transform: `translateY(${virtualItem.start}px)`, }} > {items[virtualItem.index].text} </div> ))} </div> </div> );}なぜ安全か:
- DOMノード数の制限: 表示範囲のアイテムのみをレンダリング(通常10〜20個程度)
- パフォーマンスの向上: 大量のデータでもレンダリングパフォーマンスが維持される
- メモリ使用量の削減: 不要なDOMノードを作成しない
- Reactの最適化: Reactの仮想DOMと組み合わせて、さらに効率的にレンダリング
安全に使えるユースケースのポイント:
- 適切なクリーンアップ: useEffectで追加したリソースをクリーンアップ関数で削除
- メモ化による再レンダリングの最適化: useMemoやuseCallbackを使用して不要な再レンダリングを防ぐ
- 仮想スクロールによるDOMノード数の制限: 大量のデータを表示する場合、仮想スクロールを使用
これらのユースケースを守ることで、安全で信頼性の高いReactアプリケーションを構築できます。