Home > Enterprise >  React - Debounce useEffect
React - Debounce useEffect

Time:05-23

I have created a debounced method inside my react component.

const [count, setCount] = useState(0);

const lazyLog = useCallback(
  _.debounce(() => { console.log(count) }, 5000),
  [count]
);

and I am calling it inside a useEffect, every time count is updated:

useEffect(() => {
  lazyLog();
}, [count])

The problem I am experiencing is that, as the lazyLog method is recreated on each render, the debounce functionality is not applied correctly.

You can check this snack to test the code.

How can I fix the code? As the useCallback must include the dependency... I don't find any easy way to handle this... any ideas?

CodePudding user response:

State is stale as it's not included in the dependency array of useCallback. Now if you add that the deBounce will not work.

Solution is to use a ref & hold a copy of the state in that. Then use that in the debounce. (Codesandbox)

Also - [count] should be [] in useCallback.

const refValue = useRef(count);

const lazyLog = useCallback(
    _.debounce(() => {
      console.log("debounce", refValue.current);
    }, 2000),
    [] // empty
  );

  useEffect(() => {
    refValue.current = count;
    lazyLog();
  }, [count]);

CodePudding user response:

I don't like the useDebounce hook, described in the comments, at all, because I want to debounce the callback and not the value.

I think that, in order to avoid problem with the stale state, I will pass the counter as argument, instead of consuming it directly from my state.

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

Not as clean as it could be but works fine with some minimal changes.

  • Related