useDebounce vs debounce() I got this wrong for months. Working on user forms and search where, every keystroke was triggering an API call. I reached for debounce() first. Big mistake. Here’s what I learned: Wrong - debounce() in render body // Re-creates a new debounced fn on EVERY render const handleSearch = debounce((val) => fetchResults(val), 300); Better - but needs careful handling // Stable across renders, but you manage the fn ref const handleSearch = useRef( debounce((val) => fetchResults(val), 300) ).current; Cleanest - useDebounce hook const [query, setQuery] = useState(''); const debouncedQuery = useDebounce(query, 300); useEffect(() => { if (debouncedQuery) fetchResults(debouncedQuery); }, [debouncedQuery]); // fires only after user stops typing The core difference: debounce(fn) → delays a function call. Lives outside React. Needs useRef to stay stable. useDebounce(value) → delays a state value. React-native, auto-cleanup via useEffect. No ref juggling. My rule now: → Input-driven API calls? useDebounce → Click/scroll/resize handlers? debounce() inside useRef This one pattern alone cut our unnecessary API calls by ~80% on the search feature. What’s your go-to approach? Drop it below 👇 #React #ReactHooks #FrontendEngineering #JavaScript #WebPerformance #ReactDeepDive #SeniorEngineer
Debounce vs useDebounce in React
More Relevant Posts
-
Let’s talk about useEffect. Not just how to use it… but how to use it properly. Because this is where a lot of frontend issues start. First thing to understand: useEffect is for side effects. That means anything outside the normal render flow: – API calls – subscriptions – timers – interacting with the DOM It’s not a general-purpose tool for logic. Where most people get it wrong: They treat useEffect like: “run this code when the component loads” And then you start seeing things like: – multiple API calls – infinite loops – unnecessary re-renders – state updating in circles A simple example: If you do this: useEffect(() => { fetchData(); }); That runs on every render. Now imagine what happens when state updates… The correct approach is to be intentional: – run once → use [] – run on change → add specific dependencies But here’s the shift that changed things for me: I stopped asking “where can I use useEffect?” And started asking “do I even need useEffect here?” Because in many cases, you don’t. Instead: – derive values directly during render – use event handlers for interactions – use tools like React Query (TanStack Query) for data fetching React Query handles: – caching – background updates – loading & error states – request deduplication So you don’t have to manually manage all of that inside useEffect. That shift alone removes a lot of bugs. useEffect is not a “run code” tool. It’s a synchronisation tool. Once you understand that… your code becomes simpler and more predictable. #React #ReactQuery #Frontend #WebDevelopment #JavaScript #SoftwareEngineering
To view or add a comment, sign in
-
-
⚛️ 𝗜𝗺𝗽𝗿𝗼𝘃𝗶𝗻𝗴 𝗥𝗲𝗮𝗰𝘁 𝗣𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲 — 𝗨𝘀𝗶𝗻𝗴 𝗖𝗼𝗱𝗲 𝗦𝗽𝗹𝗶𝘁𝘁𝗶𝗻𝗴 As React applications grow, bundle size increases — which directly impacts initial load time. Common problem: • large JS bundle • slow first load • unnecessary code loaded upfront A better production approach is 𝗖𝗼𝗱𝗲 𝗦𝗽𝗹𝗶𝘁𝘁𝗶𝗻𝗴. ❌ 𝗪𝗶𝘁𝗵𝗼𝘂𝘁 𝗖𝗼𝗱𝗲 𝗦𝗽𝗹𝗶𝘁𝘁𝗶𝗻𝗴 𝘪𝘮𝘱𝘰𝘳𝘵 𝘋𝘢𝘴𝘩𝘣𝘰𝘢𝘳𝘥 𝘧𝘳𝘰𝘮 "./𝘋𝘢𝘴𝘩𝘣𝘰𝘢𝘳𝘥"; 𝘪𝘮𝘱𝘰𝘳𝘵 𝘙𝘦𝘱𝘰𝘳𝘵𝘴 𝘧𝘳𝘰𝘮 "./𝘙𝘦𝘱𝘰𝘳𝘵𝘴"; 𝘪𝘮𝘱𝘰𝘳𝘵 𝘚𝘦𝘵𝘵𝘪𝘯𝘨𝘴 𝘧𝘳𝘰𝘮 "./𝘚𝘦𝘵𝘵𝘪𝘯𝘨𝘴"; All components load upfront — even if not used immediately. ❌ 𝗪𝗶𝘁𝗵𝗼𝘂𝘁 𝗖𝗼𝗱𝗲 𝗦𝗽𝗹𝗶𝘁𝘁𝗶𝗻𝗴 𝘪𝘮𝘱𝘰𝘳𝘵 { 𝘭𝘢𝘻𝘺, 𝘚𝘶𝘴𝘱𝘦𝘯𝘴𝘦 } 𝘧𝘳𝘰𝘮 "𝘳𝘦𝘢𝘤𝘵"; 𝘤𝘰𝘯𝘴𝘵 𝘋𝘢𝘴𝘩𝘣𝘰𝘢𝘳𝘥 = 𝘭𝘢𝘻𝘺(() => 𝘪𝘮𝘱𝘰𝘳𝘵("./𝘋𝘢𝘴𝘩𝘣𝘰𝘢𝘳𝘥")); 𝘤𝘰𝘯𝘴𝘵 𝘙𝘦𝘱𝘰𝘳𝘵𝘴 = 𝘭𝘢𝘻𝘺(() => 𝘪𝘮𝘱𝘰𝘳𝘵("./𝘙𝘦𝘱𝘰𝘳𝘵𝘴")); 𝘧𝘶𝘯𝘤𝘵𝘪𝘰𝘯 𝘈𝘱𝘱() { 𝘳𝘦𝘵𝘶𝘳𝘯 ( <𝘚𝘶𝘴𝘱𝘦𝘯𝘴𝘦 𝘧𝘢𝘭𝘭𝘣𝘢𝘤𝘬={<𝘱>𝘓𝘰𝘢𝘥𝘪𝘯𝘨...</𝘱>}> <𝘋𝘢𝘴𝘩𝘣𝘰𝘢𝘳𝘥 /> <𝘙𝘦𝘱𝘰𝘳𝘵𝘴 /> </𝘚𝘶𝘴𝘱𝘦𝘯𝘴𝘦> ); } Now components load 𝗼𝗻𝗹𝘆 𝘄𝗵𝗲𝗻 𝗻𝗲𝗲𝗱𝗲𝗱. 📌 Where this helps most: • large dashboards • admin panels • multi-page apps • heavy third-party libraries 📌 𝗣𝗿𝗼𝗱𝘂𝗰𝘁𝗶𝗼𝗻 𝗕𝗲𝗻𝗲𝗳𝗶𝘁𝘀: • faster initial load • reduced bundle size • better performance • improved user experience 📌 𝗕𝗲𝘀𝘁 𝗣𝗿𝗮𝗰𝘁𝗶𝗰𝗲𝘀: • split at route level • avoid over-splitting • use meaningful fallbacks • monitor bundle size Loading everything at once works — but splitting wisely improves performance significantly. 💬 Curious — do you apply code splitting at route level or component level? #ReactJS #CodeSplitting #Performance #FrontendDevelopment #JavaScript #WebDevelopment #SoftwareEngineering #Optimization
To view or add a comment, sign in
-
I spent 3 hours debugging a “simple” frontend issue… and it turned out to be one line. The problem? An API was getting called on every keystroke. Network tab = chaos 👀 Dozens of API calls for a single search. 👉 The issue: No debouncing. Here’s what the code looked like before: useEffect(() => { if (!query) return; fetch(`https://lnkd.in/eNE6UBeq) .then(res => res.json()) .then(data => setData(data)); }, [query]); Every keypress → API call ❌ Here’s the fix (debouncing): useEffect(() => { if (!query) return; const timer = setTimeout(() => { fetch(`https://lnkd.in/eNE6UBeq) .then(res => res.json()) .then(data => setData(data)); }, 300); return () => clearTimeout(timer); }, [query]); ✅ API calls reduced by ~70% ✅ Smoother UI ✅ Better user experience Lesson: Frontend performance isn’t just about what you render… It’s about when you trigger things. Small change. Big impact. Have you used debouncing or throttling in your apps? Where did it make the biggest difference? #frontend #reactjs #javascript #webperformance #softwareengineering
To view or add a comment, sign in
-
Every useEffect that sets up a subscription, timer, or event listener must clean up after itself. ```js // Memory leak — listener accumulates on every render useEffect(() => { window.addEventListener('resize', handleResize); // No cleanup — listener is never removed }); // Correct — cleanup runs before next effect and on unmount useEffect(() => { window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); ``` Other effects that require cleanup: ```js // Timers const timer = setTimeout(callback, 1000); return () => clearTimeout(timer); // Fetch abort const controller = new AbortController(); fetch(url, { signal: controller.signal }); return () => controller.abort(); // Subscriptions const sub = observable.subscribe(handler); return () => sub.unsubscribe(); ``` Memory leaks accumulate silently. Clean up your effects — every time. #ReactJS #JavaScript #Frontend #WebDevelopment
To view or add a comment, sign in
-
Who really owns your form data? In a standard HTML input, the DOM is the boss. It holds the value in its own internal memory, and you only "ask" for it when the user hits submit. But in React, we don't like hidden state. We want every piece of data to be explicit and predictable. This is where Controlled Components come in. In this pattern, the React state is the single source of truth. The input doesn't maintain its own value. Instead, you tell the input exactly what to display using the 'value' prop, and you update that value through an 'onChange' handler that modifies the state. The input is "controlled" because its behavior is entirely driven by the React component. Why go through this extra boilerplate? It gives you total coordination over the UI. Since the data lives in your state, you can perform instant field validation, disable the submit button based on specific criteria, or even format the user's input in real-time. There is no "syncing" issue between the DOM and your logic because they are never out of alignment. Of course, controlling every single character stroke in a massive form can feel like overkill. For simple, high-performance scenarios where you just need the data at the end, Uncontrolled Components using 'refs' might be faster. But for most applications, the predictability of a controlled flow far outweighs the cost of a few extra lines of code. It ensures that what the user sees is exactly what your application "knows". #ReactJS #SoftwareEngineering #WebDevelopment #FrontendArchitecture #CodingTips #Javascript
To view or add a comment, sign in
-
Recently built a Financial Dashboard to track balances, transactions, and spending insights. Live demo :- https://lnkd.in/dVD-CPeC The goal was to design a clean, data-driven UI while keeping state management simple and scalable. Tech stack: React (Vite), JavaScript, Tailwind CSS, Zustand Key features: Balance, income, and expense tracking Spending breakdown and trend visualization Savings rate calculation Export options (CSV/JSON) Responsive, component-driven UI Focus areas: Structured state management using Zustand Reusable and maintainable component design Clear data visualization for better decision-making This project helped reinforce building production-style dashboards with a focus on performance and clarity. #React #Frontend #JavaScript #WebDevelopment #TailwindCSS
To view or add a comment, sign in
-
-
Most performance problems are not caused by heavy code. They are caused by code running too many times. A search API called on every keystroke. A scroll event firing hundreds of times. A resize event triggering expensive calculations continuously. The UI feels slow. The backend gets unnecessary load. Users feel the lag. This is where Debounce and Throttle make a huge difference. Debounce says: “Wait until the user stops.” Perfect for: ✔ Search input ✔ Form validation ✔ Auto-save ✔ Final resize calculations Throttle says: “Run, but in a controlled way.” Perfect for: ✔ Scroll tracking ✔ Mouse movement ✔ Drag events ✔ Live UI updates Simple rule: Need the final result? → Debounce Need continuous controlled updates? → Throttle Performance optimization is not always about writing faster code. Sometimes it is simply about deciding when code should run. Small decision. Massive production impact. #JavaScript #ReactJS #Debounce #Throttle #FrontendDevelopment #PerformanceOptimization #WebDevelopment #SoftwareEngineering
To view or add a comment, sign in
-
-
🚀 Understanding useRef in React — Simplified! Not all data in React should trigger a re-render. 👉 That’s where useRef becomes powerful. 💡 What is useRef? useRef is a hook that lets you store a mutable value that persists across renders—without causing re-renders. ⚙️ Basic Syntax const ref = useRef(initialValue); 👉 Access value using: ref.current 🧠 How it works Value persists across renders Updating it does NOT trigger re-render Works like a mutable container 🔹 Example const countRef = useRef(0); const handleClick = () => { countRef.current += 1; console.log(countRef.current); }; 👉 UI won’t update—but value persists 🧩 Real-world use cases ✔ Accessing DOM elements (focus, scroll) ✔ Storing previous values ✔ Managing timers / intervals ✔ Avoiding unnecessary re-renders 🔥 Best Practices (Most developers miss this!) ✅ Use useRef for non-UI data ✅ Use it for DOM access ✅ Combine with useEffect when needed ❌ Don’t use useRef for UI state ❌ Don’t expect UI updates from it ⚠️ Common Mistake // ❌ Expecting UI update countRef.current += 1; 👉 React won’t re-render 💬 Pro Insight 👉 useRef = Persist value without re-render 👉 useState = Persist value with re-render 📌 Save this post & follow for more deep frontend insights! 📅 Day 14/100 #ReactJS #FrontendDevelopment #JavaScript #ReactHooks #useRef #WebDevelopment #SoftwareEngineering #100DaysOfCode 🚀
To view or add a comment, sign in
-
-
🚀 useDeferredValue in React — Smooth UI Without Blocking Ever noticed this? 👉 Typing feels laggy when filtering large data 👉 UI freezes during heavy updates You fixed it with useTransition… Now meet its smarter sibling 👉 useDeferredValue 💡 What is useDeferredValue? useDeferredValue lets you: 👉 Delay updating a value 👉 Keep UI responsive 👉 Let React handle prioritization ⚙️ Basic Syntax const deferredValue = useDeferredValue(value); 👉 React delays updating this value 👉 Until higher priority work is done 🧠 How it works const [query, setQuery] = useState(""); const deferredQuery = useDeferredValue(query); const filteredData = useMemo(() => { return expensiveFilter(data, deferredQuery); }, [deferredQuery]); 👉 Typing stays fast 👉 Filtering happens in background 🧩 Real-world Example Search input: ❌ Without useDeferredValue: Every keystroke triggers heavy filtering UI becomes slow ✅ With useDeferredValue: Input stays smooth Results update slightly later 🔥 Key Difference vs useTransition 👉 useTransition → delays state update 👉 useDeferredValue → delays value usage ⚠️ Common Mistake // ❌ Using for simple values const value = useDeferredValue(count); 👉 Not needed for cheap operations 🔥 Best Practices ✅ Use with expensive computations ✅ Combine with useMemo ✅ Ideal for search/filter UI ❌ Don’t use everywhere blindly 💬 Pro Insight (Senior-Level Thinking) 👉 useDeferredValue improves: ✔ Perceived performance ✔ User experience 👉 Not actual speed—but responsiveness 📌 Save this post & follow for more deep frontend insights! 📅 Day 26/100 #ReactJS #FrontendDevelopment #JavaScript #ReactHooks #ConcurrentRendering #PerformanceOptimization #SoftwareEngineering #100DaysOfCode 🚀
To view or add a comment, sign in
-
-
𝐈𝐬 𝐲𝐨𝐮𝐫 `𝐮𝐬𝐞𝐄𝐟𝐟𝐞𝐜𝐭` 𝐟𝐢𝐫𝐢𝐧𝐠 𝐰𝐚𝐲 𝐭𝐨𝐨 𝐨𝐟𝐭𝐞𝐧? 𝐘𝐨𝐮 𝐦𝐢𝐠𝐡𝐭 𝐛𝐞 𝐟𝐚𝐥𝐥𝐢𝐧𝐠 𝐟𝐨𝐫 𝐚 𝐜𝐨𝐦𝐦𝐨𝐧 𝐝𝐞𝐩𝐞𝐧𝐝𝐞𝐧𝐜𝐲 𝐚𝐫𝐫𝐚𝐲 𝐭𝐫𝐚𝐩. We've all been there: you put an object or array into your `useEffect`'s dependency array, thinking it's stable. But because JavaScript compares objects and arrays by reference, even if their content is identical, `useEffect` sees a new object on every render and re-runs your effect. This can lead to performance hits, stale data, or even infinite loops. 🚫 The Problem: ```javascript function MyComponent({ data }) { const options = { id: data.id, filter: 'active' }; useEffect(() => { // This runs every render if 'options' object is new fetchData(options); }, [options]); // 'options' is a new object reference each time // ... } ``` ✅ The Fix: Stabilize with `useMemo` If your object or array doesn't logically change across renders (or only changes based on specific primitives), wrap it in `useMemo`. This memoizes the object itself, ensuring its reference remains the same unless its dependencies actually change. ```javascript function MyComponent({ data }) { const stableOptions = useMemo(() => ({ id: data.id, filter: 'active' }), [data.id]); // Only re-create if data.id changes useEffect(() => { fetchData(stableOptions); }, [stableOptions]); // Now only re-runs if stableOptions' reference changes // ... } ``` This trick is a lifesaver for optimizing `useEffect` calls, especially when dealing with complex configurations or filtering logic passed down as props. It keeps your effects clean and your app performant. What's been your biggest `useEffect` headache, and how did you solve it? #React #FrontendDevelopment #JavaScript #Performance #WebDev
To view or add a comment, sign in
More from this author
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development