Can't perform a React state update on an unmounted component... エラーにConetextが原因でハマった話
環境
- react 16.8.6
事象
React.useEffect
を使用しているコンポーネントをContext.Provider
配下に配置したところ以下のエラーが発生した。
Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function
コード例は省略するが、上記のエラー発生時にReact.useEffect
内でAPIコール、その結果をsetState
等すると何故かuseEffectの処理が無限ループする。
原因
本来はfunctional componentの外側でContext
を定義するべきだが、以下のようにfunctional componentの内側で定義していた。
export const HogeContextProvider = (props: HogeProps) => { const HogeContext = React.createContext(null); return (...
以下が正しい。
export const HogeContext = React.createContext(null); export const HogeContextProvider = (props: HogeProps) => { return ( <HogeContext.Provider value={hoge}> {props.children} </HogeContext.Provider> );
functional componentの内側は、stateの更新等で何度もコールされるのでその度にContextを再作成していたことが原因の模様。
最初はContext
をProvider配下でReact.useContext
していないことが原因かなと思って調べたら、そもそもContext
をexportしていないことに気づいて、定義位置の間違いに思い当たった。
反省
DOMがstateに対応して更新されることは当然だが、functional componentの内部の処理が何度もコールされるイメージがなかった。どういうときにコールされるのか整理したい。
React、こういう単純なミスの原因特定が難しくてハマると解決に1,2時間ぐらいは必要になってしまうこともあり辛さがある。