How to prevent a function from being called multiple times?

If you use an event handler such as onClick, onChange or onScroll and want to prevent the callback from being fired too quickly, then you can limit the rate at which callback is executed. This can be achieved in the below possible ways,

Throttling

Changes based on a time based frequency. For example, it can be used using _.throttle lodash function.

_.throttle(func, wait, options)

Lodash's _.throttle() method creates a throttled function that can only call the function parameter once every millisecond. The method expects at least two arguments, the function and time to throttle.

Debouncing

When a function is passed to Lodash's debounce function, it delays the execution of the function. It can be helpful, for example, when we want to implement search by typing in input. Rather than calling the search API request for every character entered, we should only call it after the user has stopped typing.

export default function App() {
const [results, setResults] = React.useState([])
const debouncedSearch = React.useRef(
debounce(async () => {
const response = await fetch(`/api/search?query=${query}`)
const body = await response.json()
const results = body.results.map((result) => result.name)
setResults(results)
}, 300)
).current
async function handleChange(e) {
debouncedSearch(e.target.value)
}
return (
<div>
<input
type="search"
placeholder="Enter your search"
onChange={handleChange}
/>
<ul>
{results.map((result) => (
<li key={result}>{result}</li>
))}
</ul>
</div>
)
}

Using Lodash debounce method in ReactJS is better done by wrapping it in a useRef function, since this keeps track of debounced functions and prevents the creation of them on every render.

RequestAnimationFrame throttling

When a function is used to render animation or calculate the positions of elements, we can use RequestAnimationFrame to prevent it from being fired too many times.

const rafId = requestAnimationFrame(callback);

Windows.requestAnimationFrame executes your callback every time before the browser starts the next painting of the page (usually 60 times per second). To stop it you need call cancelAnimationFrame and pass the id of request (rafId from example).


May 20, 2022
19104