𝗪𝗵𝘆 𝗰𝗮𝗻’𝘁 𝘄𝗲 𝘂𝘀𝗲 async/await 𝗱𝗶𝗿𝗲𝗰𝘁𝗹𝘆 𝗶𝗻𝘀𝗶𝗱𝗲 useEffect? Most of them try writing useEffect like this: useEffect(async () => { const data = await fetchData(); setData(data); }, []); At first glance, it looks perfectly fine. But React will show a warning. What’s the reason? The function passed to useEffect must return either: • 𝗡𝗼𝘁𝗵𝗶𝗻𝗴 • 𝗔 𝗰𝗹𝗲𝗮𝗻𝘂𝗽 𝗳𝘂𝗻𝗰𝘁𝗶𝗼𝗻 E̲x̲a̲m̲pl̲e̲ ̲o̲f̲ ̲a̲ ̲c̲l̲e̲a̲n̲u̲p ̲f̲u̲n̲c̲t̲i̲o̲n̲:̲ useEffect(() => { const id = setInterval(() => { console.log("running..."); }, 1000); return () => clearInterval(id); }, []); React uses the cleanup function to 𝗿𝗲𝗺𝗼𝘃𝗲 𝘀𝗶𝗱𝗲 𝗲𝗳𝗳𝗲𝗰𝘁𝘀 when: • the component unmounts • the effect runs again The problem with async When you write:useEffect(async () => {}) The function automatically returns a 𝗣𝗿𝗼𝗺𝗶𝘀𝗲. But React expects a 𝗰𝗹𝗲𝗮𝗻𝘂𝗽 𝗳𝘂𝗻𝗰𝘁𝗶𝗼𝗻, not a Promise. So React doesn’t know how to handle it. C̲o̲r̲r̲e̲c̲t̲ ̲P̲a̲t̲t̲e̲r̲n̲ Instead, define the async function 𝗶𝗻𝘀𝗶𝗱𝗲 𝘁𝗵𝗲 𝗲𝗳𝗳𝗲𝗰𝘁: useEffect(() => { const fetchData = async () => { const data = await getUsers(); setUsers(data); }; fetchData(); }, []); Now the useEffect function itself remains 𝘀𝘆𝗻𝗰𝗵𝗿𝗼𝗻𝗼𝘂𝘀, which is exactly what React expects. Key Takeaway Instead of memorizing the workaround, understand 𝗵𝗼𝘄 𝗥𝗲𝗮𝗰𝘁 𝗺𝗮𝗻𝗮𝗴𝗲𝘀 𝘀𝗶𝗱𝗲 𝗲𝗳𝗳𝗲𝗰𝘁𝘀 𝗮𝗻𝗱 𝗰𝗹𝗲𝗮𝗻𝘂𝗽 𝗳𝘂𝗻𝗰𝘁𝗶𝗼𝗻𝘀. That small concept helps avoid many bugs in real-world applications. #React #ReactJS #FrontendDevelopment #JavaScript #WebDevelopment #CodingInterview #SoftwareEngineering
Fixing async/await in useEffect: A React Gotcha
More Relevant Posts
-
Next.js 16.2 looks like one of those releases where the improvements are not just “nice on paper” – you can actually feel them in day-to-day development. What stood out the most: – up to 400% faster startup for the dev server; – up to 350% faster Server Components payload serialization; – 25–60% faster rendering to HTML depending on RSC payload size; – up to 2x faster image response for basic images and up to 20x faster for complex ones. What makes this release especially interesting is that it is not only about developer experience. Some of these improvements also have a direct impact on production performance. One of the coolest parts is the implementation approach itself: the Next.js team contributed a change to React to improve how Server Components payloads are processed. Instead of relying on a less efficient JSON.parse reviver path, it now uses plain JSON.parse followed by a recursive walk in pure JavaScript. That translates into much faster rendering. Another strong signal from this release is how clearly Next.js is moving toward AI-assisted development: – AGENTS.md included by default in create-next-app; – dev server lock file support; – experimental agent dev tools that expose structured browser and framework insights. It feels like the ecosystem is getting ready for a workflow where AI does not just generate code, but actually understands the running application, UI, network activity, console logs, component trees, and helps fix issues with much better context. My takeaway: Next.js 16.2 is not a cosmetic release – it is a practical upgrade focused on speed, developer experience, and the foundation for AI-native workflows. If you are working with Next.js, this feels like one of those updates worth adopting sooner rather than later. #Nextjs #React #WebDevelopment #FrontendDevelopment #JavaScript #TypeScript #Performance #ServerComponents #DeveloperExperience #AI
To view or add a comment, sign in
-
💡 Most Developers Don’t Understand Async Properly (And It Shows 👀) Let’s be brutally honest. Most developers use async/await… But when things break --- they have no idea why. We write: await fetchData(); And feel like: “Haan bhai, async likh diya… ab sab sorted hai 😎” Until production says: “bhai kuch bhi sorted nahi hai 💀” The bug was in their async flow. → They stacked awaits without understanding the execution order → They ignored the event loop → They guessed instead of reasoning Here is the truth. Async is not syntax. Async is execution. You write await fetchData() and feel in control. The engine is doing something very different. JavaScript runs on a single thread. It uses the call stack. It offloads work to Web APIs. It schedules callbacks in queues. Then the event loop decides what runs next. Microtasks run before macrotasks. Always... Look at this. console.log("Start"); setTimeout(() => console.log("Timeout"), 0); Promise.resolve().then(() => console.log("Promise")); console.log("End"); Most developers guess wrong. Actual output is clear. "Start" -> "End" -> "Promise" -> "Timeout" No randomness. No magic. Just rules. Because: -> JS doesn’t care about your intuition -> It follows the event loop strictly If you do not know these rules, you are guessing. And guessing breaks systems. 🔥 Why This Matters If you don’t understand async: -> You cannot debug race conditions -> You cannot explain failures -> You cannot scale your thinking The language is not confusing. Your mental model is incomplete. Fix that. Start predicting execution before running code. Trace the stack. Track the queue. Respect the event loop. Pro Tip... Use Chrome DevTools to debug and step through async code That is how real developers work. Syntax is the entry. Understanding execution is the skill. #JavaScript #AsyncAwait #EventLoop #WebDevelopment #SoftwareEngineering
To view or add a comment, sign in
-
-
𝐘𝐨𝐮𝐫 𝐮𝐬𝐞𝐌𝐞𝐦𝐨 𝐡𝐨𝐨𝐤 𝐦𝐢𝐠𝐡𝐭 𝐛𝐞 𝐝𝐨𝐢𝐧𝐠 𝐦𝐨𝐫𝐞 𝐡𝐚𝐫𝐦 𝐭𝐡𝐚𝐧 𝐠𝐨𝐨𝐝 𝐢𝐧 𝐑𝐞𝐚𝐜𝐭. I often see teams wrapping entire components or complex JSX trees in `useMemo` thinking it's a magic bullet to prevent re-renders. While `useMemo` can optimize expensive calculations, it's not designed to prevent component re-renders. That's `React.memo`'s job. Here's the distinction: - **`useMemo`**: Memoizes a value. If its dependencies haven't changed, it returns the previously computed value without re-running the function. This is great for heavy computations or preparing data. - **`React.memo`**: Memoizes a component. It performs a shallow comparison of props and only re-renders the component if those props have changed. Misusing `useMemo` for components can lead to: 1. **Overhead**: `useMemo` itself has a cost. If the memoized value isn't computationally expensive, the overhead of memoization might outweigh the benefits. 2. **False sense of security**: Your component might still re-render if its parent re-renders, unless the component itself is wrapped in `React.memo` (and its props are stable). **When to use what:** - Use `useMemo` for expensive calculations inside a component (e.g., filtering large arrays, complex data transformations). - Use `React.memo` to prevent unnecessary re-renders of child components when their props are stable across parent renders. Combine with `useCallback` for memoizing function props. Understanding this subtle difference can significantly impact your app's performance and prevent common optimization pitfalls. What's your biggest React performance gotcha you've had to debug? #React #FrontendDevelopment #WebDevelopment #JavaScript #Performance
To view or add a comment, sign in
-
⚛️ 𝗢𝗽𝘁𝗶𝗺𝗶𝘇𝗶𝗻𝗴 𝗦𝗲𝗮𝗿𝗰𝗵 𝗔𝗣𝗜 𝗖𝗮𝗹𝗹𝘀 𝗶𝗻 𝗥𝗲𝗮𝗰𝘁 — 𝗨𝘀𝗶𝗻𝗴 𝗗𝗲𝗯𝗼𝘂𝗻𝗰𝗶𝗻𝗴 In many React applications, search inputs trigger an API call on every keystroke. If a user types "𝗿𝗲𝗮𝗰𝘁 𝗱𝗲𝘃𝗲𝗹𝗼𝗽𝗲𝗿", the app may send 15+ API requests. This can create: • unnecessary server load • slow UI performance • poor user experience A better production approach is 𝗗𝗲𝗯𝗼𝘂𝗻𝗰𝗶𝗻𝗴. Debouncing ensures that the API call runs 𝗼𝗻𝗹𝘆 𝗮𝗳𝘁𝗲𝗿 𝘁𝗵𝗲 𝘂𝘀𝗲𝗿 𝘀𝘁𝗼𝗽𝘀 𝘁𝘆𝗽𝗶𝗻𝗴 𝗳𝗼𝗿 𝗮 𝘀𝗵𝗼𝗿𝘁 𝗱𝗲𝗹𝗮𝘆. ❌ 𝗪𝗶𝘁𝗵𝗼𝘂𝘁 𝗗𝗲𝗯𝗼𝘂𝗻𝗰𝗲 useEffect(() => { fetch(`/api/search?q=${query}`) .then(res => res.json()) .then(data => setResults(data)); }, [query]); Every keystroke → API call Typing fast → many unnecessary requests ✅ 𝗪𝗶𝘁𝗵 𝗗𝗲𝗯𝗼𝘂𝗻𝗰𝗲 useEffect(() => { const delayDebounce = setTimeout(() => { fetch(`/api/search?q=${query}`) .then(res => res.json()) .then(data => setResults(data)); }, 500); return () => clearTimeout(delayDebounce); }, [query]); Now the API call runs 𝗼𝗻𝗹𝘆 𝗮𝗳𝘁𝗲𝗿 𝘁𝗵𝗲 𝘂𝘀𝗲𝗿 𝘀𝘁𝗼𝗽𝘀 𝘁𝘆𝗽𝗶𝗻𝗴 𝗳𝗼𝗿 𝟱𝟬𝟬𝗺𝘀. 📌 Benefits in real-world applications: • Reduces unnecessary API requests • Improves application performance • Reduces backend load • Provides smoother search experience 𝗧𝗵𝗶𝘀 𝗽𝗮𝘁𝘁𝗲𝗿𝗻 𝗶𝘀 𝗰𝗼𝗺𝗺𝗼𝗻𝗹𝘆 𝘂𝘀𝗲𝗱 𝗶𝗻: • search bars • product filters • autocomplete inputs • dashboard data filters Small optimizations like this make a big difference in 𝗽𝗿𝗼𝗱𝘂𝗰𝘁𝗶𝗼𝗻 𝗥𝗲𝗮𝗰𝘁 𝗮𝗽𝗽𝗹𝗶𝗰𝗮𝘁𝗶𝗼𝗻𝘀. 💬 Curious to know: Do you usually implement debouncing using 𝘀𝗲𝘁𝗧𝗶𝗺𝗲𝗼𝘂𝘁, 𝗹𝗼𝗱𝗮𝘀𝗵.𝗱𝗲𝗯𝗼𝘂𝗻𝗰𝗲, or a custom hook? #ReactJS #FrontendDevelopment #WebDevelopment #JavaScript #SoftwareEngineering #ReactTips #Coding
To view or add a comment, sign in
-
🚀 Next.js 16.2 just dropped - and your dev server is about to feel like a different tool Vercel shipped 16.2 on March 18 and the numbers are wild. 👀 ⚡ Performance - ~87% faster startup compared to 16.1 - 400–900% faster compile times in real-world apps - Server Components payload deserialization up to 350% faster - 67–100% faster app refresh 🔥 Server Fast Refresh - The same Fast Refresh you love in the browser — now for server code - Turbopack only reloads the module that changed, not the whole server - This alone is a game-changer for Server Components DX 🤖 AI Agent Features (this is where it gets interesting) - `create-next-app` now ships with `AGENTS.md` by default — giving AI coding agents version-matched Next.js docs from day one - Browser errors are now forwarded to your terminal automatically — so AI agents that can't open a browser can still debug your app - Experimental Agent DevTools: gives agents access to React DevTools, component trees, props, hooks, PPR shells — all from the terminal 🛠️ Also packed in - Web Worker Origin for better WASM support - Subresource Integrity for JS files - Tree shaking of dynamic imports - Lightning CSS config + postcss.config.ts support - 200+ bug fixes The AI agent story is what makes this release different. Vercel isn't just optimizing for developers anymore — they're optimizing for the agents that help developers. Are you planning to upgrade? And here's a real question — do you think Vercel is optimizing Next.js mostly for their own platform, or will features like these work just as well on AWS and self-hosted setups? 👇 #nextjs #react #frontend #webdev #javascript #typescript #ai #developer #performance #turbopack
To view or add a comment, sign in
-
-
Next.js is no longer just a framework update story! There is a shift in how modern full-stack applications are built and scaled. This latest update stands out, particularly from a performance and developer experience perspective. Faster startup and compile times are not just minor improvements! They directly impact daily productivity and iteration speed in real-world development environments. Server Fast Refresh is another significant step forward. For developers working with Server Components, this can reduce friction during development and make the workflow much more efficient, especially in complex applications. What also caught my attention is the growing focus on AI-driven development. Modern frameworks are evolving not only to improve application performance but also to reshape how developers interact with tools, automate workflows, and build smarter systems. As a MERN Stack Developer actively preparing for remote opportunities across global tech hubs, I am particularly interested in technologies that enhance scalability, performance, and collaboration in distributed teams. I focus on building real-world applications that are cleanly structured, performance-oriented, and aligned with modern engineering practices. For senior developers working with Next.js in production, have you consistently experienced these performance improvements, or do they vary significantly depending on project architecture and scale? #OpenToWork #RemoteWork #MERNStack #FullStackDeveloper #Nextjs #WebDevelopment #SoftwareEngineering #Performance #ScalableSystems #Hiring #RemoteHiring
Software Architect & Senior Frontend Engineer | Team Lead | TypeScript | React | React Native | Node.js | Next.js | Ex-Walmart
🚀 Next.js 16.2 just dropped - and your dev server is about to feel like a different tool Vercel shipped 16.2 on March 18 and the numbers are wild. 👀 ⚡ Performance - ~87% faster startup compared to 16.1 - 400–900% faster compile times in real-world apps - Server Components payload deserialization up to 350% faster - 67–100% faster app refresh 🔥 Server Fast Refresh - The same Fast Refresh you love in the browser — now for server code - Turbopack only reloads the module that changed, not the whole server - This alone is a game-changer for Server Components DX 🤖 AI Agent Features (this is where it gets interesting) - `create-next-app` now ships with `AGENTS.md` by default — giving AI coding agents version-matched Next.js docs from day one - Browser errors are now forwarded to your terminal automatically — so AI agents that can't open a browser can still debug your app - Experimental Agent DevTools: gives agents access to React DevTools, component trees, props, hooks, PPR shells — all from the terminal 🛠️ Also packed in - Web Worker Origin for better WASM support - Subresource Integrity for JS files - Tree shaking of dynamic imports - Lightning CSS config + postcss.config.ts support - 200+ bug fixes The AI agent story is what makes this release different. Vercel isn't just optimizing for developers anymore — they're optimizing for the agents that help developers. Are you planning to upgrade? And here's a real question — do you think Vercel is optimizing Next.js mostly for their own platform, or will features like these work just as well on AWS and self-hosted setups? 👇 #nextjs #react #frontend #webdev #javascript #typescript #ai #developer #performance #turbopack
To view or add a comment, sign in
-
-
⚛️ React "useMemo" Hook — Why & When to Use It? In modern apps built with , performance matters. That’s where "useMemo" comes in 🚀 💡 What is "useMemo"? "useMemo" is a hook that memoizes (caches) the result of a computation so it doesn’t get recalculated on every render. 📌 Syntax: const memoizedValue = useMemo(() => { return expensiveFunction(data); }, [data]); ⚡ Why use "useMemo"? ✔ Prevents unnecessary recalculations ✔ Improves performance in heavy computations ✔ Avoids re-render slowdowns 🧠 When should you use it? - Expensive calculations (e.g., filtering, sorting large data) - Derived state that doesn’t need recalculation every render - Preventing unnecessary re-renders in child components ❌ When NOT to use it? - For simple calculations (it adds overhead) - Everywhere “just in case” — use it only when needed 🔍 Example: const sortedList = useMemo(() => { return items.sort((a, b) => a.price - b.price); }, [items]); 🚀 Pro Tip: Use "useMemo" together with "React.memo" to optimize component re-rendering effectively. 💬 Final Thought: Optimization is powerful — but only when used wisely. 👉 Do you use "useMemo" in your projects? Share your experience! #ReactJS #JavaScript #WebDevelopment #Frontend #PerformanceOptimization #CodingTips
To view or add a comment, sign in
-
Most developers use async/await. Fewer understand what’s actually happening under the hood. async/await didn’t change how JavaScript handles asynchronous code. It just made it easier to read. Under the hood: - Every async function returns a Promise - Every await pauses execution of that function - Control goes back to the call stack — nothing is blocked No magic. Just Promises + the Event Loop. Here’s what actually happens: async function getData() { const data = await fetchSomething(); console.log(data); } → getData() is called An execution context is pushed onto the call stack → await is hit 🟡 fetchSomething() runs Execution of getData() pauses (non-blocking) → Call stack is free JavaScript continues handling other work → Promise resolves ✅ Its continuation is pushed to the Microtask Queue → Event Loop checks 🔄 Call stack empty → process Microtasks first → Execution resumes 🟢 getData() continues from where it paused console.log(data) runs → Function completes Call stack is clear again This is why microtasks run before setTimeout. After the call stack is empty, the Event Loop fully drains the Microtask Queue before touching the Callback Queue. Even a 0ms setTimeout waits. console.log("start"); setTimeout(() => console.log("timeout"), 0); Promise.resolve().then(() => console.log("promise")); console.log("end"); Output: start end promise timeout async/await is just syntactic sugar over Promises. The runtime behaviour is exactly the same. Once this clicks, async bugs stop feeling random — and start feeling predictable. What part of async behavior still trips you up? #JavaScript #WebDevelopment #Frontend #AsyncAwait
To view or add a comment, sign in
-
My search API was getting called 15+ times… for a single input 😅 Yes, seriously. Every time a user typed something, API was triggered on every keystroke. 💡 Example: User types: "react" 👉 r → API call 👉 re → API call 👉 rea → API call 👉 reac → API call 👉 react → API call ⚠️ This caused: • Too many unnecessary API calls • Slower performance • Bad user experience 💡 Then I fixed it using Debouncing Instead of calling API immediately, 👉 I waited for the user to stop typing 🧠 What I changed: Added a small delay (300–500ms) If user keeps typing → cancel previous call If user stops → then call API ✅ Result: • Reduced API calls significantly • Better performance • Smooth search experience 🔥 What I learned: Not every user action needs an instant API call. #ReactJS #FrontendDeveloper #JavaScript #CodingTips #WebDevelopment
To view or add a comment, sign in
-
𝐃𝐢𝐝 𝐲𝐨𝐮 𝐤𝐧𝐨𝐰 𝐑𝐞𝐚𝐜𝐭.𝐦𝐞𝐦𝐨 𝐦𝐢𝐠𝐡𝐭 𝐛𝐞 𝐥𝐲𝐢𝐧𝐠 𝐭𝐨 𝐲𝐨𝐮 𝐚𝐛𝐨𝐮𝐭 𝐩𝐫𝐞𝐯𝐞𝐧𝐭𝐢𝐧𝐠 𝐫𝐞-𝐫𝐞𝐧𝐝𝐞𝐫𝐬? It's a fantastic tool for performance, but many developers hit a wall when their memoized component still re-renders unexpectedly. The culprit? Reference equality. `React.memo` does a shallow comparison of props. This works perfectly for primitives (strings, numbers, booleans). But when you pass objects, arrays, or functions directly as props, `React.memo` will see a "new" reference on every parent re-render, even if the contents haven't changed. Example: ```javascript const MyComponent = React.memo(({ data, onClick }) => { /* ... */ }); // In parent component: <MyComponent data={{ id: 1 }} onClick={() => console.log('clicked')} /> // ^ data and onClick will be new references on every parent render ``` Even if `id: 1` is always the same, `{ id: 1 }` creates a new object in memory each time, failing the `React.memo` check. Same goes for inline functions. The fix? Leverage `useMemo` for objects/arrays and `useCallback` for functions to ensure stable references across renders. ```javascript const memoizedData = useMemo(() => ({ id: 1 }), []); const memoizedOnClick = useCallback(() => console.log('clicked'), []); <MyComponent data={memoizedData} onClick={memoizedOnClick} /> ``` This ensures your props maintain the same reference, allowing `React.memo` to do its job effectively. It's a small detail, but crucial for optimizing complex React apps. Have you encountered this `React.memo` gotcha before? How did you debug it? #React #Frontend #Performance #JavaScript #WebDevelopment
To view or add a comment, sign in
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