
🚀 How to Handle Laggy Input in React: Debounce, useEffect, and Beyond
Have you ever built a search bar in React where every keypress triggered an update? You might have noticed your app starting to feel... sluggish. This isn't just about visuals—constant state updates on every keystroke can slow down your UI, spike network requests, and wreck performance in real-world apps.
salahuddin SK
Author
đź‘‹ Introduction
Have you ever built a search bar in React where every keypress triggered an update? You might have noticed your app starting to feel... sluggish.
This isn't just about visuals—constant state updates on every keystroke can slow down your UI, spike network requests, and wreck performance in real-world apps.
In this post, we’ll explore why this happens and multiple ways to fix it, including:
- đź§
lodash.debounce - đź› Using
useEffect+setTimeout - ⚙️ Throttle (bonus tip)
đź§Ş The Problem: Immediate State Updates
Let’s start with a basic input field:
const [name, setName] = useState('');
const handleChange = (e) => {
setName(e.target.value);
console.log(e.target.value);
};
Here’s what happens:
- Every keypress updates state (
setName) - Every update re-renders the component
console.logfires constantly
While fine for local inputs, this becomes a real problem when tied to API calls, filters, or expensive computations.
âś… Solution 1: lodash.debounce
The most common and cleanest solution: use lodash.debounce.
đź”§ How it works:
Debounce waits for a pause in user input before executing a function.
📦 Install lodash:
npm install lodash
✍️ Updated Code:
import { debounce } from 'lodash';
import { useCallback, useState } from 'react';
const [name, setName] = useState('');
const debouncedSetName = useCallback(
debounce((value) => {
setName(value);
}, 300),
[]
);
const handleChange = (e) => {
debouncedSetName(e.target.value);
};
âś… Benefits:
- Clean code
- Prevents API overload
- Smooth user experience
âś… Solution 2: useEffect + setTimeout
Don’t want to add lodash? You can achieve similar results with plain React.
đź§Ş Example:
const [inputValue, setInputValue] = useState('');
const [debouncedValue, setDebouncedValue] = useState('');
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(inputValue);
}, 300);
return () => {
clearTimeout(handler);
};
}, [inputValue]);
const handleChange = (e) => {
setInputValue(e.target.value);
};
🔍 What’s happening?
- User types →
inputValueupdates immediately setTimeoutwaits 300ms- If no new input,
debouncedValueupdates - Cleanup ensures only the last keystroke triggers a change
âś… Benefits:
- No external libraries
- More control
- Easy to test
âś… Bonus: Throttle Instead of Debounce?
While debounce waits for a pause in typing, throttle executes at intervals no matter how fast input comes.
Use throttle if you want periodic updates (e.g., every 500ms), even during typing.
Example with lodash.throttle:
import { throttle } from 'lodash';
const throttledChange = useCallback(
throttle((val) => setName(val), 500),
[]
);
đź§ Use throttle when:
- You want updates to happen regularly during input
- Ideal for tracking, logging, or animations
đź’ˇ Which Method Should You Use?
Use CaseRecommended ApproachBasic delay without extra libsuseEffect + setTimeoutClean, reusable debouncelodash.debouncePeriodic updates during typinglodash.throttle
đź§Ş Real Project Example
Here’s how we implemented lodash.debounce in a real React form:
<div className="flex flex-col items-center gap-4 p-6 bg-white shadow-lg rounded-2xl w-full max-w-md mx-auto mt-10">
<input
type="text"
onChange={handleChange}
placeholder="Enter your name"
className="px-4 py-2 border border-gray-300 rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-blue-400"
/>
<h1 className="text-xl font-semibold text-gray-800">Name: {name}</h1>
</div>
🔚 Final Thoughts
Optimizing input handling in React is more than just performance—it's about building better user experiences.
Whether you use lodash, useEffect, or throttleThese techniques will help you scale your apps confidently and professionally.
đź’¬ Have questions?
Drop a comment or message me on Instagram @learncodepro!
Comments (0)
Leave a Comment
About the Author
salahuddin SK
Sr. software Dev.
Passionate about sharing knowledge and helping developers learn new technologies.
Stay Updated
Get the latest articles and tutorials directly in your inbox.