在 onChange 函数中使用时超时不清除
Timeout not clearing when used in onChange function
我正在为我正在使用的网站创建搜索功能。当用户输入关键字时,将发送一个获取请求以检索匹配的信息。但是,每次按下一个键都让它触发,感觉很浪费。假设用户想要搜索三明治,他们很可能会很快连续输入我只想在用户停止输入一定时间后(比如 250 毫秒)触发它。我的想法是设置一个超时,将在连续击键时清除。不幸的是,超时不会重置,只会被延迟。我尝试将它放在 useEffect 挂钩中,然后超时工作正常,但我遇到了一些其他问题,促使我尝试这样做。
const onChangeBrand = (e) => {
const brand = e.target.value
setBrand(brand)
const timeout = setTimeout(()=>{
url.get(`brands?search=${encodeURI(brand.toLowerCase())}&rows=5`)
.then(res => {
setBrands(res.data)
if(res.data.length === 1 && res.data[0].urlEncoding === encodeURI(brand.toLowerCase())){
setPageType("models")
}else{
setPageType("brands")
}
})
},2500)
return () => clearTimeout(timeout);
}
如有任何帮助,我们将不胜感激!
你的想法是对的,但执行是错误的。从 onChange
处理程序返回一个函数本质上什么都不做——这在 useEffect
中可以正常工作,所以我知道它来自哪里。这种模式被称为 throttling / debouncing a function and there are tons of premade libraries out there to help you throttle a function (like lodash.throttle),但是自己旋转非常酷!
这里的关键是:
- 使用方法范围外的超时变量
- 在开始执行您的
onChange
时,检查超时变量是否有值——如果有,请清除它。
- 执行
onChange
,分配新的超时时间。
您可以在这里使用 ref
或其他东西,但我个人认为完全在组件范围之外定义超时持有者是最简单的。
let CHANGE_TIMEOUT = null;
function MyComponent(props) {
// .. component code
const onChangeBrand = (e) => {
if (CHANGE_TIMEOUT) {
// we already have a previous timeout, clear it.
clearTimeout(CHANGE_TIMEOUT);
}
const brand = e.target.value
setBrand(brand)
// Set the timeout again
CHANGE_TIMEOUT = setTimeout(()=>{
url.get(`brands?search=${encodeURI(brand.toLowerCase())}&rows=5`)
.then(res => {
setBrands(res.data)
if(res.data.length === 1 && res.data[0].urlEncoding === encodeURI(brand.toLowerCase())){
setPageType("models")
}else{
setPageType("brands")
}
})
},2500);
}
// .. other component code here
}
我正在为我正在使用的网站创建搜索功能。当用户输入关键字时,将发送一个获取请求以检索匹配的信息。但是,每次按下一个键都让它触发,感觉很浪费。假设用户想要搜索三明治,他们很可能会很快连续输入我只想在用户停止输入一定时间后(比如 250 毫秒)触发它。我的想法是设置一个超时,将在连续击键时清除。不幸的是,超时不会重置,只会被延迟。我尝试将它放在 useEffect 挂钩中,然后超时工作正常,但我遇到了一些其他问题,促使我尝试这样做。
const onChangeBrand = (e) => {
const brand = e.target.value
setBrand(brand)
const timeout = setTimeout(()=>{
url.get(`brands?search=${encodeURI(brand.toLowerCase())}&rows=5`)
.then(res => {
setBrands(res.data)
if(res.data.length === 1 && res.data[0].urlEncoding === encodeURI(brand.toLowerCase())){
setPageType("models")
}else{
setPageType("brands")
}
})
},2500)
return () => clearTimeout(timeout);
}
如有任何帮助,我们将不胜感激!
你的想法是对的,但执行是错误的。从 onChange
处理程序返回一个函数本质上什么都不做——这在 useEffect
中可以正常工作,所以我知道它来自哪里。这种模式被称为 throttling / debouncing a function and there are tons of premade libraries out there to help you throttle a function (like lodash.throttle),但是自己旋转非常酷!
这里的关键是:
- 使用方法范围外的超时变量
- 在开始执行您的
onChange
时,检查超时变量是否有值——如果有,请清除它。 - 执行
onChange
,分配新的超时时间。
您可以在这里使用 ref
或其他东西,但我个人认为完全在组件范围之外定义超时持有者是最简单的。
let CHANGE_TIMEOUT = null;
function MyComponent(props) {
// .. component code
const onChangeBrand = (e) => {
if (CHANGE_TIMEOUT) {
// we already have a previous timeout, clear it.
clearTimeout(CHANGE_TIMEOUT);
}
const brand = e.target.value
setBrand(brand)
// Set the timeout again
CHANGE_TIMEOUT = setTimeout(()=>{
url.get(`brands?search=${encodeURI(brand.toLowerCase())}&rows=5`)
.then(res => {
setBrands(res.data)
if(res.data.length === 1 && res.data[0].urlEncoding === encodeURI(brand.toLowerCase())){
setPageType("models")
}else{
setPageType("brands")
}
})
},2500);
}
// .. other component code here
}