Created
April 23, 2020 17:31
-
-
Save Quaese/30c1852daa1149d226a2c6cd6599a068 to your computer and use it in GitHub Desktop.
useSimpleDebounce Hook for React
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Idea from: https://stackoverflow.com/questions/23123138/perform-debounce-in-react-js | |
*/ | |
import { useState } from "react"; | |
// https://github.com/slorber/react-async-hook | |
import { useAsync } from "react-async-hook"; | |
// https://github.com/Andarist/use-constant | |
import useConstant from "use-constant"; | |
// https://github.com/slorber/awesome-debounce-promise | |
import AwesomeDebouncePromise from "awesome-debounce-promise"; | |
const callback = (val, e) => { | |
console.log("callback: ", val, e); | |
return val; | |
}; | |
// Generic reusable hook | |
const useSimpleDebounce = (idFn = callback, delay = 500) => { | |
// Handle the input text state | |
const [debounceText, setDebounceText] = useState(""); | |
// Handle event state | |
const [debounceEvent, setDebounceEvent] = useState(null); | |
// Debounce the original search async function | |
const debouncedFunction = useConstant(() => | |
AwesomeDebouncePromise(idFn, delay) | |
); | |
// The async callback is run each time the text changes, | |
// but as the search function is debounced, it does not | |
// fire a new request on each keystroke | |
const debouncedResults = useAsync(async () => { | |
return debouncedFunction(debounceText, debounceEvent); | |
}, [debouncedFunction, debounceText, debounceEvent]); | |
// Return everything needed for the hook consumer | |
return { | |
// stateful variables for input value | |
debounceText, | |
setDebounceText, | |
// return value after debouncing the callback | |
debouncedResults, | |
// stateful variables for firing event | |
debounceEvent, | |
setDebounceEvent | |
}; | |
}; | |
export default useSimpleDebounce; | |
/** | |
* Example to use the hook: | |
* | |
* | |
``` | |
import React from "react"; | |
import useSimpleDebounce from "./hooks/useSimpleDebounce"; | |
export default function SimpleDebounce() { | |
// Declare debouncer (hook) variables | |
// callback that should be debounced | |
const myCallback = (val, e) => { | |
if (e && e.which === 13) { | |
console.log("Enter ... release search ...", val, e && e.which); | |
} | |
}; | |
// wrap callback in debouncer | |
const useSimpleDebounceWrapper = () => useSimpleDebounce(myCallback, 1000); | |
// get necessary variables from wrapper | |
const { | |
debounceText, | |
setDebounceText, | |
setDebounceEvent | |
} = useSimpleDebounceWrapper(); | |
return ( | |
<div className="App"> | |
{ \/* Use debouncer in JSX *\/} | |
<input | |
value={debounceText} | |
onChange={e => setDebounceText(e.target.value)} | |
onKeyUp={e => { | |
e.persist(); | |
setDebounceEvent(e); | |
}} | |
/> | |
</div> | |
); | |
} | |
``` | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment