反应 - 去抖动+ 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

虽然不尽如人意,但只要稍加改动就可以正常工作。