React Can’t perform a React state update on an unmounted component. が出た時に確認すること
ポーリング処理などを行っている時に遭遇する「Can’t perform a React state update on an unmounted component.」の対処方法についてです。
このエラーは、アンマウントされたコンポーネントのstateに対して更新を行おうとした際に発生します。
コンポーネント内でsetIntervalなどを使って、stateに更新をかけている場合などです。
例を見てみます。
以下は親ページです。liタグをクリックすると、HogeコンポーネントとPage2という文字列を切り替えています。
import Hoge from "./Hoge";
import {useState} from "react";
const App = () => {
const [page, setPage] = useState(1);
return (
<div>
<ul>
<li onClick={() => setPage(1)}>page1</li>
<li onClick={() => setPage(2)}>page2</li>
</ul>
{page === 1 ? <Hoge/> : 'Page2'}
</div>
);
};
export default App;
問題のコンポーネントです。
import {useEffect, useState} from "react";
const Hoge = () => {
const [count, setCount] = useState(0);
useEffect(() => {
setInterval(() => {
setCount(c => c + 1);
}, 1000);
}, []);
return (
<div>
<h2>Hoge</h2>
<div>{count}</div>
</div>
);
};
export default Hoge;
stateとしてcountという値を持っています。
そして、useEffect内で1秒ごとにcountをインクリメントする処理をしています。
ここで問題となるのは、Hogeコンポーネントがアンマウントされても、setIntervalが実行され続けるところです。
そうすると、countに対して更新をかけ続けようとするのですが、countはHogeがアンマウントされたことによって消えているので、今回のエラーが起きます。
以下のように、コンポーネントのアンマウント時にclearIntervalしてあげればエラーが解消します。
import {useEffect, useState} from "react";
const Hoge = () => {
const [count, setCount] = useState(0);
useEffect(() => {
const timerId = setInterval(() => {
setCount(c => c + 1);
}, 1000);
return () => {
clearInterval(timerId);
}
}, []);
return (
<div>
<h2>Hoge</h2>
<div>{count}</div>
</div>
);
};
export default Hoge;
ディスカッション
ピンバック & トラックバック一覧
[…] React Can’t perform a React state update on an unmounted component. が出た時に確認するこ… […]