Reactコンポーネントの強制再レンダリング(setStateなし)
By hunglv, at: 2025年9月22日9:07
Estimated Reading Time: __READING_TIME__ minutes


問題:
Reactでは、状態に意味のある変化がない場合でも、コンポーネントの再レンダリングを強制する必要がある場合があります。たとえば、コンポーネントのローカル状態には影響しない外部イベント(例:WebSocket、イベントエミッタ、またはカスタムストア)をリッスンしていて、それでも視覚的な更新が必要な場合があります。
よくあるシナリオ:
useEffect(() => {
someObservable.on('data', () => {
// しかし、ここで状態は設定されていません
// コンポーネントは再レンダリングされません!
});
}, []);
解決策:ダミー状態またはReducerを使用する
関数コンポーネントの場合:
ダミーのuseStateまたはuseReducerを使用して、手動で再レンダリングをトリガーします。
const [, forceUpdate] = useReducer(x => x + 1, 0);
useEffect(() => {
const handleUpdate = () => forceUpdate();
someObservable.on('data', handleUpdate);
return () => someObservable.off('data', handleUpdate);
}, []);
クラスコンポーネントの場合:
this.forceUpdate()メソッドを使用します。
componentDidMount() {
this.listener = () => this.forceUpdate();
someObservable.on('data', this.listener);
}
componentWillUnmount() {
someObservable.off('data', this.listener);
}
長所と短所
長所:
-
非Reactの状態ソース(外部ストアやイベントエミッタなど)との統合を可能にします。
-
不要な状態変数を追加することなく、一度限りのトリガーに対してシンプルで効果的です。
-
再レンダリングをトリガーするだけの意味のない状態によってコンポーネントを混乱させるのを避けます。
短所:
-
宣言的ではないため、Reactの通常の状態/データフローをバイパスしています。
-
過剰に使用すると、アーキテクチャ上の問題を示している可能性があります。リファクタリングするか、適切な状態管理ソリューションを使用することを検討してください。
-
クラスコンポーネントでforceUpdate()を使用することは、最終手段と見なされ、保守が困難なコードにつながる可能性があります。
開発者向けヒント:
再レンダリングを頻繁に強制している場合は、コンポーネントの構造または状態管理アプローチの更新が必要かどうかを検討してください。React Context、Zustand、Redux、またはカスタムフックを使用すると、よりクリーンなソリューションが提供される場合があります。