How to Perform Debounce

Debouncing and Timeout in React

I don't think React hooks are a good fit for a throttle or debounce function. From what I understand of your question you effectively want to debounce the handleChangeProductName function.

Here's a simple higher order function you can use to decorate a callback function with to debounce it. If the returned function is invoked again before the timeout expires then the timeout is cleared and reinstantiated. Only when the timeout expires is the decorated function then invoked and passed the arguments.

const debounce = (fn, delay) => {
let timerId;
return (...args) => {
clearTimeout(timerId);
timerId = setTimeout(() => fn(...args), delay);
}
};

Example usage:

export default function ProductInputs({ handleChangeProductName }) {
const debouncedHandler = useCallback(
debounce(handleChangeProductName, 200),
[handleChangeProductName]
);

return (
<TextField
fullWidth
label="Name"
variant="outlined"
size="small"
name="productName"
value={formik.values.productName}
helperText={formik.touched.productName ? formik.errors.productName : ""}
error={formik.touched.productName && Boolean(formik.errors.productName)}
onChange={(e) => {
formik.setFieldValue("productName", e.target.value);
debouncedHandler(e.target.value);
}}
/>
);
}

If possible the parent component passing the handleChangeProductName callback as a prop should probably handle creating a debounced, memoized handler, but the above should work as well.

How to implement debounce in React.js?

There are some changes which you need to make,

First debouncedOnChangeHandler variable holds the function like,

   const debouncedOnChangeHandler = (e) => {
debounce(onChangeHandler(e), 1000);
};

But whereas this doesn't pass the onChangeHandler as expected argument for debounce method.

So you need to just passdown the debounce function along with required parameters like,

const debouncedOnChangeHandler = debounce(onChangeHandler, 1000);

Second: You need to remove value={name} which is not needed in this context.

Forked Codesanbox:

Edit mutable-mountain-ec3q9j

Can someone explain the debounce function in Javascript

The code in the question was altered slightly from the code in the link. In the link, there is a check for (immediate && !timeout) BEFORE creating a new timout. Having it after causes immediate mode to never fire. I have updated my answer to annotate the working version from the link.

function debounce(func, wait, immediate) {

// 'private' variable for instance

// The returned function will be able to reference this due to closure.

// Each call to the returned function will share this common timer.

var timeout;

// Calling debounce returns a new anonymous function

return function() {

// reference the context and args for the setTimeout function

var context = this,

args = arguments;

// Should the function be called now? If immediate is true

// and not already in a timeout then the answer is: Yes

var callNow = immediate && !timeout;

// This is the basic debounce behaviour where you can call this

// function several times, but it will only execute once

// [before or after imposing a delay].

// Each time the returned function is called, the timer starts over.

clearTimeout(timeout);

// Set the new timeout

timeout = setTimeout(function() {

// Inside the timeout function, clear the timeout variable

// which will let the next execution run when in 'immediate' mode

timeout = null;

// Check if the function already ran with the immediate flag

if (!immediate) {

// Call the original function with apply

// apply lets you define the 'this' object as well as the arguments

// (both captured before setTimeout)

func.apply(context, args);

}

}, wait);

// Immediate mode and no wait timer? Execute the function..

if (callNow) func.apply(context, args);

}

}

/////////////////////////////////

// DEMO:

function onMouseMove(e){

console.clear();

console.log(e.x, e.y);

}

// Define the debounced function

var debouncedMouseMove = debounce(onMouseMove, 50);

// Call the debounced function on every mouse move

window.addEventListener('mousemove', debouncedMouseMove);

How implement debounce for event listener ? Problem with storage event

Well just set the debounced function as event listener?

function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};

const storageEventCb = () => console.error(1);

// Define the debounced function
const debouncedCb = debounce(storageEventCb, 1500);

window.addEventListener('storage', debouncedCb);

Debounce function issue

The debounce function returns another function, which you can think of like an object of a class (it has a "memory" of timer, which is setTimeout id), and you always invoke the same function created with debounce() function. But in the first example, you create new debounced function on every input event, which creates new object unaware of previous timeouts.



Related Topics



Leave a reply



Submit