How to Create a Custom Debounce Hook with React
source link: https://www.telerik.com/blogs/how-to-create-custom-debounce-hook-react
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
How to Create a Custom Debounce Hook with React
In this article, we will look at how to create a custom debounce hook with React.
React is a JavaScript library used for creating interactive web frontend applications. It is one of the most popular libraries because of its easy-to-use API.
Most recent versions of React provide the Hooks API, which lets us create frontend JavaScript apps with function components. Hooks provides the logic for React function components.
One common feature that is implemented in frontend web apps is adding debounce for inputs. Debouncing lets us delay actions after an input’s value is changed. In this article, we will look at how to create a custom debounce hook with React.
Custom Hooks
We can create our own custom React hooks based on the basic hooks provided by React.
To do this, we create a function that calls the hooks and returns the values we want. Then we can get the returned values from our custom hook and do what we want with them in our components or other hooks.
For instance, we can make our own hook to get data and return it.
To do this, we write:
import { useCallback, useEffect, useState } from "react";
const useFetch = (url) => {
const [data, setData] = useState();
const [loading, setLoading] = useState();
const getData = useCallback(async () => {
setLoading(true);
const res = await fetch(url);
const json = await res.json();
setData(json);
setLoading(false);
}, [url]);
useEffect(() => {
getData();
}, [getData]);
return { data, loading };
};
to define the useFetch
hook.
A custom hook is just a pure function that uses other hooks. And a pure function is a function that takes some inputs and returns some outputs without committing any side effects.
In our useFetch
hook, we define the data
and loading
states with the useState
hook.
And then we call the useCallback
hook with a function to make a request to the url
with fetch
.
We then call json
to get the JSON response body and call setData
to set the data
state to the json
response object.
Also, we call setLoading
to set the loading
state to true
when the request is going to start and set it to false
when
it’s done.
And then we call useEffect
with a callback that calls getData
to make the request when the getData
function is defined.
Finally, we return the data
and loading
state values in an object.
A Breakdown of the React useEffect Hook
React Hooks aim to solve the difficulties of logic reuse by enabling us to write components that have access to features like state, context, lifecycle methods, ref, etc. In this article, we’ll focus on the powerful useEffect hook, which allows us to perform side effects in our function components.
Once we define the useFetch
hook, we can use it directly in a component.
To do this, we write:
export default function App() {
const { data, loading } = useFetch("https://yesno.wtf/api");
return (
<div className="App">{loading ? "loading" : JSON.stringify(data)}</div>
);
}
We call useFetch
with the URL we want to make the request to.
And we destructure the returned object into the data
and loading
variables.
Then we render the response as a JSON string if loading
is false
and 'loading'
otherwise.
Create a Custom Debounce React Hook
Likewise, we can create our own custom debounce React hook with the same method.
Debouncing will add a delay before we do something. So when we want to debounce an input, we delay setting the value as a state’s value by a short time period.
To do this, we create the useDebounce
hook by writing:
import { useEffect, useRef, useState } from "react";
const useDebounce = (value, delay = 500) => {
const [debouncedValue, setDebouncedValue] = useState("");
const timerRef = useRef();
useEffect(() => {
timerRef.current = setTimeout(() => setDebouncedValue(value), delay);
return () => {
clearTimeout(timerRef.current);
};
}, [value, delay]);
return debouncedValue;
};
Like the useFetch
hook, we create the useDebounce
hook by defining a function with the given name. It takes the input value
and the delay
for the debounce time period in milliseconds. In it, we call the useState
hook to define the debouncedValue
state.
And we call useEffect
with a callback that calls setTimeout
with a callback that calls setDebouncedValue
when value
changes or after a delay
in milliseconds.
The returned timer ID number is assigned to the timerRef
's current
value.
The useRef
hook creates a ref, which is a value that can be kept even after the component or hook is rendered or rerun.
We also return a function that calls clearTimeout
to clear the timer when value
or delay
is changed.
Finally, we return the debouncedValue
so we can use it in our component.
Then, to use useDebounce
in our component, we write:
export default function App() {
const [value, setValue] = useState("");
const debouncedValue = useDebounce(value, 500);
const search = useCallback(async () => {
const res = await fetch(
`https://demo.dataverse.org/api/search?q=${debouncedValue}`
);
const json = await res.json();
console.log(json);
}, [debouncedValue]);
useEffect(() => {
search();
}, [debouncedValue, search]);
return (
<div className="App">
<input value={value} onChange={(e) => setValue(e.target.value)} />
</div>
);
}
We define the value
state with the useState
hook.
Next, we call the useDebounce
hook we created with the value
state and a 500 millisecond delay before returning the debouncedValue
.
And then we define the search
function that makes a get request with fetch
to get data from an API.
We then get the JSON response body with res.json
and then log that value.
The function is used as an argument of the useCallback
hook so we can avoid redefining the function when the debouncedValue
value didn’t change.
Then we call the useEffect
hook with a callback that calls the search
function when debouncedValue
or the search
function
has changed.
Finally, we add an input that sets the value
prop to the value
state and the onChange
prop to a function that calls setValue
to set value
to the input value.
As a result, when we type in something into the input, the debouncedValue
—which is set to value
—is returned after the delay we specified as the second argument of
useDebounce
.
And then the useEffect
callback is called to make the request with the latest debouncedValue
.
Conclusion
One common feature that is implemented in web frontend apps is adding debounce for inputs. Debouncing lets us delay actions after an input’s value is changed.
We can make our own debounce hook so we can easily do some action when we change an input’s value after a delay.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK