[解決済み] Reactフック - タイムアウトとインターバルをクリアする正しい方法
2022-04-26 15:35:59
質問
を使用すると、なぜか
setTimeout
関数を実行すると、私のリアクトコンポーネントは無限にコンソール.ログを出力し始めます。全て動いているのですが、PCが地獄のようにラグを始めます。
タイムアウトで状態が変化し、コンポーネントが再レンダリングされ、新しいタイマーが設定される、などと言っている人がいます。今、私はそれが正しいことをクリアする方法を理解する必要があります。
export default function Loading() {
// if data fetching is slow, after 1 sec i will show some loading animation
const [showLoading, setShowLoading] = useState(true)
let timer1 = setTimeout(() => setShowLoading(true), 1000)
console.log('this message will render every second')
return 1
}
異なるバージョンのコードでクリアしても、役に立ちません。
const [showLoading, setShowLoading] = useState(true)
let timer1 = setTimeout(() => setShowLoading(true), 1000)
useEffect(
() => {
return () => {
clearTimeout(timer1)
}
},
[showLoading]
)
解決方法は?
定義
return () => { /*code/* }
関数内部
useEffect
は毎回実行される
useEffect
が実行されます (コンポーネントマウント時の最初のレンダリングを除く) とコンポーネントアンマウント時 (コンポーネントを表示しなくなった場合) に実行されます。
これは、タイムアウトやインターバルを使用したり、クリアするための作業方法です。
import { useState, useEffect } from "react";
const delay = 5;
export default function App() {
const [show, setShow] = useState(false);
useEffect(
() => {
let timer1 = setTimeout(() => setShow(true), delay * 1000);
// this will clear Timeout
// when component unmount like in willComponentUnmount
// and show will not change to true
return () => {
clearTimeout(timer1);
};
},
// useEffect will run only one time with empty []
// if you pass a value to array,
// like this - [data]
// than clearTimeout will run every time
// this value changes (useEffect re-run)
[]
);
return show ? (
<div>show is true, {delay}seconds passed</div>
) : (
<div>show is false, wait {delay}seconds</div>
);
}
他のコンポーネントでタイムアウトやインターバルをクリアする必要がある場合。
import { useState, useEffect, useRef } from "react";
const delay = 1;
export default function App() {
const [counter, setCounter] = useState(0);
const timer = useRef(null); // we can save timer in useRef and pass it to child
useEffect(() => {
// useRef value stored in .current property
timer.current = setInterval(() => setCounter((v) => v + 1), delay * 1000);
// clear on component unmount
return () => {
clearInterval(timer.current);
};
}, []);
return (
<div>
<div>Interval is working, counter is: {counter}</div>
<Child counter={counter} currentTimer={timer.current} />
</div>
);
}
function Child({ counter, currentTimer }) {
// this will clearInterval in parent component after counter gets to 5
useEffect(() => {
if (counter < 5) return;
clearInterval(currentTimer);
}, [counter, currentTimer]);
return null;
}
関連
-
Vueの一般的な組み込みディレクティブの説明
-
[解決済み】"フォームが接続されていないため、フォームの送信がキャンセルされました "というエラーの取得について
-
jq は html ページとデータを動的に分割する。
-
[解決済み] React NativeとReactの違いは何ですか?
-
[解決済み] Reactのstateとpropsの違いとは?
-
[解決済み] React HooksでcomponentWillMount()を使用するには?
-
[解決済み】react hooksで`setState`コールバックを使用する方法
-
[解決済み】React HooksのPushメソッド(useState)?
-
[解決済み】React Hooks useState()でオブジェクトを使用する。
-
[解決済み】React Hooks useEffectでoldValuesとnewValuesを比較する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vueの要素ツリーコントロールに破線を追加する説明
-
vue3.0プロジェクトのアーキテクチャを構築するための便利なツール
-
Javascript Bootstrapのグリッドシステム、ナビゲーションバー、ローテーションの説明
-
vue+webrtc(Tencent cloud)ライブ機能の実践を実現するために
-
[解決済み】React - TypeError: 未定義のプロパティ 'props' を読み取ることができない。
-
[解決済み】JavaScriptエラー(Uncaught SyntaxError: Unexpected end of input)
-
[解決済み】React Uncaught Error: 対象コンテナが DOM 要素でない [重複]。
-
[解決済み】 Uncaught TypeError : undefined のプロパティ 'replace' を読み取れない In Grid
-
[解決済み】「.addEventListener is not a function」なぜこのエラーが発生するのか?
-
[解決済み】setInterval内でReactのstateフックを使用するとstateが更新されない。