Skip to content

Instantly share code, notes, and snippets.

@acburdine
Last active April 25, 2019 11:35
Show Gist options
  • Save acburdine/c3db53a07bc8c9fa517272f601e3909e to your computer and use it in GitHub Desktop.
Save acburdine/c3db53a07bc8c9fa517272f601e3909e to your computer and use it in GitHub Desktop.
React useState hook with debounce

React useDebouncedState hook

Why?

I was building a component that did address autocompletion against a GraphQL endpoint using react-apollo. The value of the input field was used to search for addresses, but I didn't want every single keystroke to result in a new GraphQL query. So, I needed some sort of debounce function (Apollo doesn't provide this natively).

While I could have used a class component for something like this, I wanted to see if it could be done more simply with Hooks. This is what I came up with.

import { useState, useEffect } from 'react';
/**
* Custom Hook to create a "debounced" state.
*
* Example Usage:
* ```js
* function MyComponent() {
* const [rawValue, debouncedValue, setValue] = useDebouncedState('', 500);
*
* <input value={rawValue} onChange={newVal => setValue(newVal)} />
* <MyChildComponent value={debouncedValue} />
* }
* ```
*
* @param initialState {Any} Initial state
* @param delay {Number} Delay for the debounce, in milliseconds
* @return {Array} array containing the raw value, the debounced value, and the setState function.
*/
export default function useDebouncedState(initialState, delay) {
const [state, setState] = useState(initialState);
const [debouncedState, setDebouncedState] = useState(initialState);
useEffect(() => {
const timer = setTimeout(() => setDebouncedState(state), delay);
return () => clearTimeout(timer);
}, [state]);
return [state, debouncedState, setState];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment