ys memos

Blog

reactのfirebaseSDKでmemory learkワーニング


react

2021/09/20


React で Firebase SDK を使っていて,ブラウザに以下の warning が出てきた.


warning_log
Warning: 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.

この警告は,見る限りメモリリークが発生している.タイミングとしては,component の unmount 時である.発生箇所はuseEffect()となっている.

今回は心当たりが合ったので簡単に問題を修正できた.



base
const App = () => {
	...
  useEffect(() => {
    onAuthStateChanged(auth, (user) => {
      if (user) {
        setLoggedIn(true);
        setImage(googlesignin_disabled);
      } else {
        setLoggedIn(false);
      }
    });
  }, []);

	return (
		...
	)
}

fixed
 const App = () => {
   ...
   useEffect(() => {
-    onAuthStateChanged(auth, (user) => {
+    const unsubscribe = onAuthStateChanged(auth, (user) => {
       if (user) {
         setLoggedIn(true);
         setImage(googlesignin_disabled);
       } else {
         setLoggedIn(false);
       }
     });
+    return unsubscribe;
   }, []);

   return (
     ...
   )
 }

useEffect()により component の mount 時に onAuthStateChanged()で,Auth 状態の変更を subscribe していた.

元コードでは subscribe の解除が行われていない.そこで,onAuthStateChanged()の戻り値であるUnsubscribe型を保持しておき,unmount 時に呼び出す.


「何故この書き方をすると・・・?」などの疑問については,おそらく React 公式の Hooks の説明ページの中のuseEffectの説明を見てもらえばよいでしょう.日本語では「副作用フック」のような和訳がなされていた気がする.


関連タグを探す