Everything looked correct… but we were sending the wrong data to the backend. At some point, you can started noticing something strange in your dashboard. Nothing was obviously broken. The UI updated. The inputs worked as expected.But the data didn’t match what users were typing. Imagine this - you type “John” into a search field. The UI shows “John”. But the API request… still uses the previous value. Here’s a simplified version of what we had: function Dashboard() { const [filters, setFilters] = React.useState({ search: '' }); const fetchData = React.useCallback(() => { api.get('/users', { params: filters }); }, []); React.useEffect(() => { fetchData(); }, [filters]); return ( <input value={filters.search} onChange={(e) => setFilters({ search: e.target.value }) } /> ); } At first glance, it feels correct. The effect depends on filters. Whenever filters change, we fetch data. So what could go wrong? The issue was hiding in a place that looked “optimized”. That useCallback. It was created once, with an empty dependency array. Which means it captured the value of filters at the very beginning… and never updated it. So every time fetchData ran, it used an old version of the filters. That’s why the UI and the backend slowly drifted apart. The user saw one thing. The API received another. The fix was simple: const fetchData = React.useCallback(() => { api.get('/users', { params: filters }); }, [filters]); Or just removing useCallback entirely. What made this bug tricky is that nothing actually crashed.Everything looked fine. But the data was wrong. It was a good reminder that React doesn’t magically keep values up to date inside functions. Closures remember the state from the moment they were created. And sometimes… that’s exactly the problem. Have you run into something like this before? #reactjs #javascript #frontend #webdevelopment #softwareengineering #react #webdev
Dmitrii Lobanov’s Post
More Relevant Posts
-
🚀 Stop treating Server State like UI State. As React developers, we’ve all been there: building "custom" fetching logic with useEffect and useState. It starts with one loading spinner and ends with a nightmare of manual cache-busting and race conditions. When I started migrating my data-fetching to TanStack Query, it wasn't just about "fewer lines of code"—it was about a shift in mindset. The Real Game Changers: Declarative vs. Imperative: Instead of telling React how to fetch (and handle errors/loading), you describe what the data is and when it should be considered stale. Focus Refetching: This is a huge UX win. Seeing data update automatically when a user switches back to the tab feels like magic to them, but it’s just one config line for us. Standardized Patterns: It forces the whole team to handle errors and loading states the same way, which makes code reviews much faster. The Win: In a recent refactor, I replaced a tangled mess of global state syncs and manual useEffect triggers with a few useQuery hooks. I was able to delete a significant chunk of boilerplate while fixing those "stale data" bugs that always seem to haunt client-side apps. The takeaway: Don't reinvent the cache. Use tools that let you focus on the product, not the plumbing. 👇 Question for the devs: Are you using TanStack Query for everything, or are you finding that Next.js Server Actions and the native fetch cache are enough for your use cases now? #reactjs #nextjs #frontend #webdev #tanstackquery #javascript
To view or add a comment, sign in
-
Your users are waiting for tasks they'll never see. Here's the fix. 👇 Most devs write POST routes where emails, analytics, and syncs all run before the response is returned. The user sits there waiting — not because the data isn't ready, but because your side-effects are blocking the thread. Next.js 15 ships a built-in after() API. Response fires instantly. Background work runs after. No queues, no infra, no nonsense. ❌ Blocking tasks The user's request hangs until every side-effect (email, analytics, sync) finishes. One slow service delays the whole response — bad UX, worse performance. ✅ after() — fire & forget Response is sent instantly. Background work runs after — no blocking, no extra infrastructure, no queue needed. Works with Server Actions and Route Handlers. #NextJS #NextJS15 #WebDevelopment #JavaScript #TypeScript #100DaysOfCode #CleanCode #FrontendDeveloper #SoftwareEngineer #WebDev #NodeJS #FullStackDeveloper #Programming #ServerActions #BackendDevelopment #ReactServer #APIDesign #WebPerformance
To view or add a comment, sign in
-
-
𝐈𝐬 𝐲𝐨𝐮𝐫 𝐮𝐬𝐞𝐄𝐟𝐟𝐞𝐜𝐭 𝐫𝐮𝐧𝐧𝐢𝐧𝐠 𝐭𝐨𝐨 𝐨𝐟𝐭𝐞𝐧, 𝐨𝐫 𝐧𝐨𝐭 𝐚𝐭 𝐚𝐥𝐥 𝐰𝐡𝐞𝐧 𝐲𝐨𝐮 𝐞𝐱𝐩𝐞𝐜𝐭 𝐢𝐭 𝐭𝐨? 𝐘𝐨𝐮'𝐫𝐞 𝐩𝐫𝐨𝐛𝐚𝐛𝐥𝐲 𝐟𝐚𝐥𝐥𝐢𝐧𝐠 𝐟𝐨𝐫 𝐭𝐡𝐢𝐬 𝐜𝐨𝐦𝐦𝐨𝐧 𝐭𝐫𝐚𝐩. One of the sneakiest `useEffect` issues comes from non-primitive values in its dependency array. If you declare a function or object directly inside your component and include it in `useEffect`'s dependencies without memoizing it, React sees a "new" function/object on every render. This means your effect will re-run endlessly, or worse, refer to stale data if you're trying to optimize with an empty array. **Bad Example:** ```jsx function MyComponent() { const fetchData = async () => { /* ... */ }; // New function on every render useEffect(() => { fetchData(); }, [fetchData]); // fetchData changes every render, so effect re-runs } ``` **The Fix:** Memoize your functions with `useCallback` and objects with `useMemo`. This tells React to only create a new instance if its dependencies change. ```jsx import React, { useCallback, useEffect } from 'react'; function MyComponent() { const fetchData = useCallback(async () => { // Your actual data fetching logic console.log("Fetching data..."); }, []); // Depend on nothing if the logic itself doesn't change useEffect(() => { fetchData(); }, [fetchData]); // fetchData only changes if its own dependencies change } ``` This ensures your effect runs only when `fetchData` actually changes (which, in this `useCallback` example, is never after the initial mount, making it efficient). It's a subtle distinction, but mastering `useCallback` and `useMemo` for `useEffect` dependencies is key to stable and performant React apps. Have you ever battled an infinite `useEffect` loop because of this? What was your debugging "aha!" moment? #React #JavaScript #Frontend #WebDevelopment #ReactHooks
To view or add a comment, sign in
-
Nobody knew what was wrong. Users were hitting timeout alerts. Pages were hanging. We checked everything — API responses, network calls, server logs. Everything looked fine on paper. We were stumped. Then one of my teammates opened React DevTools Profiler. We were shocked. Every single component was re-rendering. Not once. Not twice. On every minor state update, the entire tree was lighting up. The app was redrawing itself from scratch every few seconds — and the API never even got a fair chance to respond before the UI had already timed out. The answer was in our React code the whole time. We just weren't looking there. Here's what was actually causing it: 1. useEffect chains nobody noticed: Effect A updated state → triggered Effect B → triggered Effect C. Three effects. One user action. Dozens of cascading re-renders. Silent, invisible, and absolutely devastating for performance. 2. No memoization where it mattered: Expensive computations — filtering large datasets, transforming API responses — running fresh on every single render. The UI was doing work it had already done, over and over. 3. State living too high in the tree: A state update at the top was trickling down and forcing re-renders in components that had nothing to do with that state change. 4. Components doing too much: UI, data fetching, and transformation logic all in one place — so any change anywhere triggered everything everywhere. The fix wasn't one big refactor. It was systematic: — Audited and collapsed redundant useEffect chains — Moved state closer to where it was actually used — Added useMemo and useCallback only where Profiler confirmed the cost — Separated data logic from render logic Result: timeout alerts gone. Page load dropped significantly. Same API. Same backend. Zero infrastructure changes. The backend was never the problem. One thing I now tell every developer of my team: "Profile first. Fix second. Always." Because the bug you assume is never the bug that's actually there. Have you ever spent days chasing a bug that turned out to be somewhere you never expected? 👇 #React #ReactJS #Frontend #MERN #JavaScript #TypeScript #WebPerformance #SoftwareEngineering
To view or add a comment, sign in
-
The "Ghost in the API": How I fixed a major rendering lag 👻 While working on a complex user dashboard at Codes Thinker, I encountered a frustrating performance bottleneck. Every time a user triggered a data fetch, the entire UI would "freeze" for a split second before updating. Even with a fast backend API, the user experience felt "heavy" and unprofessional. The Challenge: We were fetching large, nested JSON objects directly inside a parent component. Every time the API responded, the entire component tree re-rendered, causing a visible performance lag during data transformation. The Solution: React Query: I implemented React Query to handle caching. This ensured that if a user requested the same data twice, the result was instant. Data Transformation: Instead of passing the raw "heavy" object to components, I mapped the data into a lighter format immediately after fetching. Optimistic UI: I used Tailwind CSS to create smooth skeleton loaders, making the app feel faster while the data was still loading. The Result: The rendering lag disappeared, and the user experience became fluid. Sometimes, being a Senior Frontend Developer is about knowing when not to fetch data as much as how to fetch it. Have you ever faced a stubborn API lag? How did you tackle it? Let’s share some dev stories! 👇 #RESTAPI #NextJS #PerformanceOptimization #MERNStack #WebDevelopment #CleanCode #ReactJS #TailwindCSS
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
-
🚀 Exploring React’s cache() — A Hidden Performance Superpower Most developers focus on UI optimization… But what if your data fetching could be smarter by default? Recently, I explored the cache() utility in React — and it completely changed how I think about data fetching in Server Components. 💡 What’s happening here? Instead of calling the same API multiple times across components, we wrap our function with: import { cache } from 'react'; const getCachedData = cache(fetchData); Now React automatically: ✅ Stores the result of the first call ✅ Reuses it for subsequent calls ✅ Avoids unnecessary duplicate requests ⚡ Why this matters Imagine multiple components requesting the same data: Without caching → Multiple API calls ❌ With cache() → One call, shared result ✅ This leads to: Better performance Reduced server load Cleaner and more predictable data flow 🧠 The real beauty You don’t need: External caching libraries Complex state management Manual memoization React handles it for you — elegantly. 📌 When to use it? Server Components Reusable data-fetching logic Expensive or repeated API calls 💬 Takeaway Modern React is not just about rendering UI anymore — it’s becoming a data-aware framework. And features like cache() prove that the future is about writing less code with smarter behavior. #ReactJS #WebDevelopment #PerformanceOptimization #JavaScript #FrontendDevelopment #FullStack #ReactServerComponents #CodingTips #SoftwareEngineering
To view or add a comment, sign in
-
-
Most Developers Debate REST vs GraphQL… But Very Few Understand When to Use What. Let’s simplify this with a real-world analogy 👉 REST is like ordering a fixed meal combo You get predefined items. Even if you only want fries… you still get the burger and drink. 👉 GraphQL is like a buffet You pick exactly what you want. No waste. No extra. Just what you need. REST ✔ Simple & predictable ✔ Uses standard HTTP methods (GET, POST, PUT, DELETE) ✔ Easy caching ❌ Multiple API calls for related data ❌ Over-fetching or under-fetching GraphQL ✔ Single endpoint ✔ Fetch exactly what you need (nothing more, nothing less) ✔ Great for complex & evolving UIs ✔ Supports real-time (Subscriptions) ❌ More complex setup ❌ Harder caching ❌ Risk of heavy/abusive queries if not controlled So what should YOU choose? 👉 Building simple, stable APIs? → Go with REST 👉 Building dynamic, data-heavy frontend apps? → GraphQL wins 💭 The truth is: It’s not about which is better… It’s about which fits your problem. For more insightful content checkout below: 🟦 𝑳𝒊𝒏𝒌𝒆𝒅𝑰𝒏 - https://lnkd.in/dwi3tV83 ⬛ 𝑮𝒊𝒕𝑯𝒖𝒃 - https://lnkd.in/dkW958Tj 🟥 𝒀𝒐𝒖𝑻𝒖𝒃𝒆 - https://lnkd.in/dDig2j75 or Priya Frontend Vlogz 🔷 𝐓𝐰𝐢𝐭𝐭𝐞𝐫 - https://lnkd.in/dyfEuJNt #frontend #javascript #interviewquestions #interview #interviewpreparation #Frontend #Backend #APIDesign #SystemDesign #GraphQL #REST #WebDevelopment
To view or add a comment, sign in
-
-
Most React devs think they understand useEffect. They don't. And it's costing them subtle bugs in prod. Here's the one thing nobody explains clearly: The cleanup function doesn't run when you think it does. Say you're fetching user data based on a userId prop: > the buggy version useEffect(() => { fetch(`/api/user/${userId}`) .then(res => res.json()) .then(data => setUser(data)); }, [userId]); Looks fine, right? It's not. If userId changes from 1 → 2 quickly, maybe the user is clicking through a list, both requests are in flight. Whichever resolves last wins. You could end up showing user 1's data on user 2's profile. That's a race condition, and it's completely silent. Here's how you fix it with an AbortController: > the correct version useEffect(() => { const controller = new AbortController(); fetch(`/api/user/${userId}`, { signal: controller.signal }) .then(res => res.json()) .then(data => setUser(data)) .catch(err => { if (err.name !== 'AbortError') throw err; }); return () => controller.abort(); }, [userId]); Now when userId changes, React runs the cleanup - which aborts the in-flight request, before firing the new effect. No stale data. No race. No mystery bug at 2am. The cleanup function is not just for "removing event listeners." It's your undo button for whatever the effect started. Timers? Clear them. Subscriptions? Unsubscribe. Requests? Abort them. I've seen this bite senior devs on dashboards, search inputs, and paginated lists more times than I can count. If your useEffect fetches data and has no cleanup, there's a bug waiting to happen. #React #MERN #WebDevelopment #JavaScript #FrontendDevelopment #ReactNative
To view or add a comment, sign in
-
🚀Why Loading Too Much Data Can Break Your Application While working on an infinite scrolling feature in React, I came across an important real-world problem 👇 ❌ Problem: If the backend sends a very large amount of data at once, both the website and server start slowing down. 🔍 Why does this happen? ▪️ Large API responses take more time to transfer over the network. ▪️The browser struggles to render too many items at once. ▪️Memory usage increases significantly. ▪️Server load increases when handling heavy requests. 👉 I was using the GitHub API, and it helped me understand how important it is to control the amount of data being fetched. 📦 Solution: Pagination + Infinite Scrolling ▪️Instead of loading everything at once: ▪️Fetch data in smaller chunks (pagination) ▪️Load more data only when needed (infinite scroll). ⚡ Benefits: ▪️Faster initial load time ▪️Better performance ▪️Smooth user experience ▪️Reduced server stress 💡 What I learned: ▪️Efficient data fetching is crucial in frontend development ▪️Performance optimization matters as much as functionality ▪️Real-world applications are built with scalability in mind 🎯 Key takeaway: It’s not about how much data you can load — it’s about how efficiently you load it. #ReactJS #JavaScript #WebDevelopment #Frontend #Performance #LearningInPublic #CodingJourney
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