[英]React JS setTimeout gets executed multiple times
大家好,我是 React JS 的新手,我陷入了一個無法弄清楚原因的問題。 因此,我正在嘗試制作一個僅在用戶完成輸入后才觸發 API 調用的搜索字段組件。 發生的事情是,在setTimeout中鍵入搜索后會執行多次。 恐怕這會造成多次不必要的 api 調用。 非常感謝您的幫助。 謝謝!
主要的.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
<App />
)
應用程序.tsx
import { useState } from 'react'
import fetchData from './utils/fetch'
import { WeatherModel } from './model/Weather'
function SearchField() {
let timer = 0
const [city, setCity] = useState('New York')
const handleFetchWeather = async () => {
const data: WeatherModel = await fetchData(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${WEATHER_API_KEY}&units=metric`)
console.log(data)
}
const handleSetCity = (e) => {
if(timer) clearTimeout(timer)
setCity(e.target.value)
timer = setTimeout(() => {
console.log(city)
// handleFetchWeather()
}, 2000)
}
return (
<div className="search">
<input type="text" placeholder="Search city..." onChange={handleSetCity} />
</div>
)
}
export default SearchField
您可以使用去抖動:
這是一個例子:
useEffect(() => {
let debounce;
if (debounce) {
clearTimeout(debounce);
debounce = null;
}
debounce = setTimeout(() => {
// DO SOMETHING AFTER TIMEOUT ENDS
setSearchEntry(searchValue);
}, 1 * 1000);
}, [setSearchEntry, searchValue]);
祝你好運 :)
我同意 debounce 解決方案,但如果你不知道,這段代碼對你來說可能更簡單,所以每次組件重新渲染時,計時器再次設置為 0,所以為了保持值,想象一下你需要把它放在一個狀態,就像這樣:
import { useState } from "react";
function SearchField() {
const [city, setCity] = useState("New York");
const [timer, setTimer] = useState(0);
const handleFetchWeather = async () => {
const data = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${WEATHER_API_KEY}&units=metric`
);
console.log(data);
};
const handleSetCity = (e) => {
if (timer) {
clearTimeout(timer);
}
setCity(e.target.value);
setTimer(
setTimeout(() => {
console.log(city);
// handleFetchWeather()
}, 2000)
);
};
return (
<div className="search">
<input
type="text"
placeholder="Search city..."
onChange={handleSetCity}
/>
</div>
);
}
export default SearchField;
現在,每次重新渲染,組件都會記住它之前的值;)
輸入字段中的 onChange 事件將在每個新字符輸入時觸發,在此處了解更多信息。
我認為在這種情況下,最好的解決方案是添加觸發 handleSetCity() 的提交按鈕,並且您的 onChange 應該設置一個狀態變量,以便更容易處理數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.