DEV Community

loading...

Discussion on: Debounce Any Effect by Creating Your Own useDebouncedEffect Hook

Collapse
gyandeeps profile image
Gyandeep Singh

Nice example. It was fun playing around with it.

It works in this simplified case but if their is someother higher priority update going on in the same component it will not work. The issue is that the instance of fn is always new which triggers the useEffect inside useDebouncedEffect. I think using useCallback for that would fix the issue.

function useDebouncedEffect(fn, deps, time) {
  const dependencies = [...deps, fn, time];
  useEffect(() => {
    const timeout = setTimeout(fn, time);
    return () => {
      clearTimeout(timeout);
    };
  }, dependencies);
}

export default function App() {
  const [text, setText] = useState("");
  const [debounced, setDebounced] = useState("");
  const [count, setCount] = useState(0);

  const deb = useCallback(() => {
    setDebounced(text);
  }, [text]);

  useDebouncedEffect(deb, [text], 1000);

  // to mock a higher priority frequent update
  useEffect(() => {
    setInterval(() => {
      setCount((c) => c + 1);
    }, 500);
  }, []);

  return (
    <div className="App">
      <input
        onChange={(e) => {
          setText(e.target.value);
        }}
        value={text}
      />
      <p>{debounced}</p>
      <p>{count}</p>
    </div>
  );
}
Collapse
nas5w profile image
Nick Scialli (he/him) Author

I hadn’t thought about this! I’m going to try it out an amend the post later :). Thank you!

Collapse
gyandeeps profile image
Gyandeep Singh

Not sure in every case people gonna run into this but their is a chance.