使用 React Hook 去抖或节流
Debounce or throttle with react hook
当来自输入字段的搜索查询参数更改时,我需要发出 api 请求,但前提是该字段不为空。
我正在测试在此站点上找到的几个答案,但无法使它们正常工作
第一个 this 带有自定义挂钩的
export function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}
现在在我的组件中我这样做
const debouncedTest = useDebounce(() => {console.log("something")}, 1000);
但这似乎在每次重新渲染时都会被调用,而不管任何参数,我需要能够在 useEffect 中调用它,就像这样
useEffect(() => {
if (query) {
useDebounce(() => {console.log("something")}, 1000);
} else {
//...
}
}, [query]);
这当然行不通
另一种使用 lodash 的方法
const throttledTest = useRef(throttle(() => {
console.log("test");
}, 1000, {leading: false}))
但是我如何从上面的 useEffect 触发它?我不明白如何进行这项工作
谢谢
你的hook签名和你调用的时候不一样
也许你应该按照这些思路做一些事情:
const [state, setState] = useState(''); // name it whatever makes sense
const debouncedState = useDebounce(state, 1000);
useEffect(() => {
if (debouncedState) functionCall(debouncedState);
}, [debouncedState])
我可以在这里快速指出一两件事。
useEffect(() => {
if (query) {
useDebounce(() => {console.log("something")}, 1000);
} else {
//...
}
}, [query]);
从技术上讲,您不能执行上述操作,useEffect
不能嵌套。
通常debounce
与钩子无关。因为它是一个简单的函数。所以你应该首先寻找一个可靠的去抖动,创建一个或使用 lodash.debounce
。然后构造您的代码以调用 debounce(fn)
。 Fn
是您要延迟的原始函数。
另外 debounce
将处理经常变化的情况,这就是为什么你要应用去抖动来降低频率。因此,在 useEffect
.
中很少见
const debounced = debounce(fn, ...)
const App = () => {
const onClick = () => { debounced() }
return <button onClick={onClick} />
}
还有一个常见的问题,大家可能会在App
里面使用debounce功能。这也不正确,因为 App
每次呈现时都会被触发。
稍后我可以提供一个相对更详细的解决方案。如果您也能解释一下您想做什么,将会有所帮助。
当来自输入字段的搜索查询参数更改时,我需要发出 api 请求,但前提是该字段不为空。
我正在测试在此站点上找到的几个答案,但无法使它们正常工作
第一个 this 带有自定义挂钩的
export function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}
现在在我的组件中我这样做
const debouncedTest = useDebounce(() => {console.log("something")}, 1000);
但这似乎在每次重新渲染时都会被调用,而不管任何参数,我需要能够在 useEffect 中调用它,就像这样
useEffect(() => {
if (query) {
useDebounce(() => {console.log("something")}, 1000);
} else {
//...
}
}, [query]);
这当然行不通
另一种使用 lodash 的方法
const throttledTest = useRef(throttle(() => {
console.log("test");
}, 1000, {leading: false}))
但是我如何从上面的 useEffect 触发它?我不明白如何进行这项工作
谢谢
你的hook签名和你调用的时候不一样
也许你应该按照这些思路做一些事情:
const [state, setState] = useState(''); // name it whatever makes sense
const debouncedState = useDebounce(state, 1000);
useEffect(() => {
if (debouncedState) functionCall(debouncedState);
}, [debouncedState])
我可以在这里快速指出一两件事。
useEffect(() => {
if (query) {
useDebounce(() => {console.log("something")}, 1000);
} else {
//...
}
}, [query]);
从技术上讲,您不能执行上述操作,useEffect
不能嵌套。
通常debounce
与钩子无关。因为它是一个简单的函数。所以你应该首先寻找一个可靠的去抖动,创建一个或使用 lodash.debounce
。然后构造您的代码以调用 debounce(fn)
。 Fn
是您要延迟的原始函数。
另外 debounce
将处理经常变化的情况,这就是为什么你要应用去抖动来降低频率。因此,在 useEffect
.
const debounced = debounce(fn, ...)
const App = () => {
const onClick = () => { debounced() }
return <button onClick={onClick} />
}
还有一个常见的问题,大家可能会在App
里面使用debounce功能。这也不正确,因为 App
每次呈现时都会被触发。
稍后我可以提供一个相对更详细的解决方案。如果您也能解释一下您想做什么,将会有所帮助。