反应 - 去抖动+ useEffect
React - Debounce + useEffect
我在我的 React 组件中创建了一个去抖动方法。
const [count, setCount] = useState(0);
const lazyLog = useCallback(
_.debounce(() => { console.log(count) }, 5000),
[count]
);
我在 useEffect 中调用它,每次 count
更新时:
useEffect(() => {
lazyLog();
}, [count])
我遇到的问题是,由于在每次渲染时重新创建了 lazyLog 方法,debounce
功能未正确应用。
您可以检查此 snack 以测试代码。
如何修复代码?由于 useCallback 必须包含依赖项...我找不到任何简单的方法来处理这个...有什么想法吗?
状态已过时,因为它未包含在 useCallback
的依赖项数组中。现在,如果您添加 deBounce
将不起作用。
解决方案是使用 ref
并保存其中的状态副本。然后在 debounce
中使用它。 (Codesandbox)
另外 - [count]
在 useCallback
中应该是 []
。
const refValue = useRef(count);
const lazyLog = useCallback(
_.debounce(() => {
console.log("debounce", refValue.current);
}, 2000),
[] // empty
);
useEffect(() => {
refValue.current = count;
lazyLog();
}, [count]);
我根本不喜欢评论中描述的 useDebounce
挂钩,因为我想要去抖动回调而不是值。
我认为,为了避免陈旧状态的问题,我会将计数器作为参数传递,而不是直接从我的状态中使用它。
export default function App() {
const [count, setCount] = useState(0);
const lazyLog = useCallback(
_.debounce((count) => { console.log(count); }, 5000),
[]
);
useEffect(() => {
lazyLog(count);
}, [count])
return (
<View>
<Text onPress={() => setCount(prevCount => prevCount + 1)}>
Increase
</Text>
</View>
);
}
https://snack.expo.dev/67W9HnsRD
虽然不尽如人意,但只要稍加改动就可以正常工作。
我在我的 React 组件中创建了一个去抖动方法。
const [count, setCount] = useState(0);
const lazyLog = useCallback(
_.debounce(() => { console.log(count) }, 5000),
[count]
);
我在 useEffect 中调用它,每次 count
更新时:
useEffect(() => {
lazyLog();
}, [count])
我遇到的问题是,由于在每次渲染时重新创建了 lazyLog 方法,debounce
功能未正确应用。
您可以检查此 snack 以测试代码。
如何修复代码?由于 useCallback 必须包含依赖项...我找不到任何简单的方法来处理这个...有什么想法吗?
状态已过时,因为它未包含在 useCallback
的依赖项数组中。现在,如果您添加 deBounce
将不起作用。
解决方案是使用 ref
并保存其中的状态副本。然后在 debounce
中使用它。 (Codesandbox)
另外 - [count]
在 useCallback
中应该是 []
。
const refValue = useRef(count);
const lazyLog = useCallback(
_.debounce(() => {
console.log("debounce", refValue.current);
}, 2000),
[] // empty
);
useEffect(() => {
refValue.current = count;
lazyLog();
}, [count]);
我根本不喜欢评论中描述的 useDebounce
挂钩,因为我想要去抖动回调而不是值。
我认为,为了避免陈旧状态的问题,我会将计数器作为参数传递,而不是直接从我的状态中使用它。
export default function App() {
const [count, setCount] = useState(0);
const lazyLog = useCallback(
_.debounce((count) => { console.log(count); }, 5000),
[]
);
useEffect(() => {
lazyLog(count);
}, [count])
return (
<View>
<Text onPress={() => setCount(prevCount => prevCount + 1)}>
Increase
</Text>
</View>
);
}
https://snack.expo.dev/67W9HnsRD
虽然不尽如人意,但只要稍加改动就可以正常工作。