After building a personal journal app with React 18, Tailwind CSS, and a Node/Express backend, I ran it through a full code audit. The result was a masterclass in the gaps between "it works" and "it's production-ready." Here's what came up: BUG FIXES → apiFetch was crashing on non-JSON error responses (502/504 HTML pages). Added a try/catch around res.json() with a readable fallback message. → The date formatter was silently producing "Invalid Date" for null/undefined values. Now returns '—'. → Math.random() IDs were used throughout. Swapped to crypto.randomUUID() for collision-safe IDs. → A useEffect in Toast was missing onDone in its dependency array — a subtle stale closure bug. → API responses were trusted to always be arrays. They're not. Array.isArray() guards added everywhere. ERROR HANDLING → Every save/delete was fire-and-forget. Wrapped in try/catch with inline user-visible errors. → Deletes had no confirmation dialog. One misclick = permanent data loss. → If the initial data load failed, the app rendered silently empty. Now shows a proper error screen. → Added a cancelled flag in useEffect to prevent state updates on unmounted components. CODE QUALITY → Extracted a useJournalData() custom hook to keep App lean. → Created reusable <FormError /> and <SaveButton /> components — the same pattern was copy-pasted 4 times. → BLANK_ENTRY/POST/PLACE were constants sharing a reference. Made them factory functions so each form gets a fresh object. → Replaced repeated new Date().toISOString().slice(0,10) with a todayISO() helper. PERFORMANCE → Filtered and sorted lists were recalculated on every render. Wrapped in useMemo. → Event callbacks recreated on every render. Wrapped in useCallback. ACCESSIBILITY → Clickable cards had no keyboard support. Added role="button", tabIndex, and onKeyDown Enter handlers. → Inputs were missing htmlFor/id associations and autoComplete attributes. → Decorative emoji lacked aria-hidden="true". The app "worked" before. Now it's resilient. The gap between working code and production code isn't about features — it's about what happens when things go wrong. Github repo : https://lnkd.in/dPz6Wqp7 #React #WebDevelopment #CodeQuality #JavaScript #FrontendDevelopment
Arhum Butt’s Post
More Relevant Posts
-
Most developers think they understand the event loop. Until performance starts breaking in production. I wrote a short breakdown on: • Why the event loop becomes a bottleneck • What actually blocks it (it’s not always obvious) • Simple patterns to avoid performance issues No fluff. Just practical insights you can apply immediately. If you’re working with JS (browser or Node), this matters more than you think. Read here: https://lnkd.in/g_8n8gvn
To view or add a comment, sign in
-
My React app was slow. Users were complaining. I added a loading spinner and called it a fix. That was the wrong answer. The real problem was I had no idea why my components were re-rendering, how often, or what to do about it. I was just writing React and hoping it would be fast. It wasn't. React re-renders a component every time its state or props change — and every child too, whether they need it or not. In a real app, one state update at the top can trigger dozens of unnecessary renders. The fix starts with structure: keep state as close as possible to the component that actually uses it. React.memo tells React to skip re-rendering a component if its props didn't change. But if you're passing new objects or functions on every render, memo won't help — every render creates a new reference. That's where useCallback and useMemo come in. One stabilizes function references, the other caches expensive calculations. Don't make them a habit though — reach for them only when you have a confirmed performance problem. Code splitting is something most developers delay too long. React.lazy with Suspense loads components only when needed. Settings pages, admin panels, rarely-opened modals — none of that should be in your initial bundle. For lists, never use index as a key prop — it confuses the reconciler and causes unnecessary DOM updates. And if you're rendering hundreds of rows, virtualize with react-window. Render only what's visible. React 18 also batches multiple state updates in the same event handler into one re-render. But async functions and timeouts don't always get that benefit — worth understanding before you chase phantom performance issues. Now the part that changes everything: the React Compiler. For years, memoization was manual work — you wrote useMemo, useCallback, and React.memo yourself and hoped you got it right. The React Compiler, introduced in React 19, does all of that automatically at build time. It analyzes your components, understands what depends on what, and inserts the right optimizations before your code hits the browser. You write clean React. The compiler handles the rest. It doesn't fix a bloated bundle or restructure your app — so everything above still matters. But manually tracking every function reference just to avoid a re-render? That era is ending. Fast React apps were never magic. They're just the result of understanding what React does — and now, letting the compiler do the tedious parts.
To view or add a comment, sign in
-
-
Using index as a key is dangerous Every React developer has written this at least once. items.map((item, index) => ( <li key={index}>{item}</li> )) Looks fine. Works fine. But it isn't This is Post 5 of the series: 𝗥𝗲𝗮𝗰𝘁 𝗨𝗻𝗱𝗲𝗿 𝘁𝗵𝗲 𝗛𝗼𝗼𝗱 Where I explain what React is actually doing behind the scenes. Here's what actually happens when you use index as key: You delete one item from a list. React doesn't know which item was removed. It just looks at positions. So it re-renders everything from that index downward. Input states get mismatched. Animations break. Bugs appear that you can't even reproduce consistently. And... No error. Just... wrong behavior. 🔑 Here's what React actually needs: A key isn't just something unique. It needs to be stable, unique, AND tied to the data — not the position. ❌ key={index} → breaks on delete, sort, filter ❌ key={Math.random()} → new key every render = React destroys and recreates the node ✅ key={item.id} → stable, reliable, React knows exactly who is who The rule is simple: If your list can ever be reordered, filtered, or deleted from... index as key will silently break your UI. Use your data's ID. If it doesn't have one, generate it at creation — not during render. const newItem = { id: crypto.randomUUID(), name: "New Task" } One tiny prop. Massive impact on how React tracks your entire list. In Post 6 of React Under the Hood: What Happens When You Call setState Follow Farhaan Shaikh if you want to understand react more deeply. 👉 Read the previous post - Understanding diffing algorithm: https://lnkd.in/dzW3NP_V #SoftwareEngineering #ReactJS #WebDevelopment #JavaScript #FrontendDevelopment #BuildInPublic #LearnInPublic #ReactUnderTheHood
To view or add a comment, sign in
-
If you’re writing 5 files just to toggle a boolean... 🛑 You’re not scaling. You’re over-engineering. For a long time, I used Redux for almost everything in React. And honestly? It felt powerful... but also unnecessarily complex for 90% of my use cases. Recently, I switched to Zustand — and the difference is 🔥 Why Zustand just makes sense: ✅ Zero Boilerplate No Providers. No massive folder structures. Just create and use. ✅ Hook-Based If you know useState, you already understand Zustand. It feels like native React. ✅ Performance First It handles selective re-renders out of the box. Only the components that need the data will update. 💻 The "Store" is this simple: JavaScript import { create } from 'zustand' const useStore = create((set) => ({ count: 0, inc: () => set((state) => ({ count: state.count + 1 })), })) Use it anywhere: JavaScript function Counter() { const { count, inc } = useStore() return <button onClick={inc}>{count}</button> } ⚡ 𝗣𝗥𝗢 𝗠𝗢𝗩𝗘 (Most developers miss this): Use selectors to grab only what you need: const count = useStore((state) => state.count) This keeps your app lightning-fast even as your state grows massive. 📈 Since switching, my code is: → Simpler → Cleaner → Easier to maintain 🟣 Team Redux (The tried and true) 🐻 Team Zustand (The minimalist) #ReactJS #Zustand #JavaScript #WebDevelopment #Frontend #CodingTips #SoftwareEngineering
To view or add a comment, sign in
-
-
> **Stop guessing where your files go. Here's the React folder structure every developer needs to know. 🗂️** > > After years of messy codebases, late-night debugging sessions, and onboarding nightmares — the secret to a scalable frontend isn't just your code. It's **how you organize it.** > > Here's what each folder does and why it matters: > 📡 **API** — All your backend connections in one place. No more hunting for fetch calls. > 🎨 **Assets** — Static files, images, fonts. Clean and centralized. > 🧩 **Components** — Reusable UI building blocks. Write once, use everywhere. > 🌐 **Context** — Global state without prop drilling chaos. > 📦 **Data** — Static JSON content and constants. > 🪝 **Hooks** — Custom logic extracted and reusable across the entire app. > 📄 **Pages** — One folder per route. Clean, readable, scalable. > 🔄 **Redux** — Advanced state management for complex apps. > ⚙️ **Services** — Business logic and frontend services, separated from UI. > 🛠️ **Utils** — Helper functions that every file in your app will thank you for. > > A well-structured project isn't a luxury — **it's what separates junior from senior developers.** > > Save this. Share it with your team. Your future self will thank you. 💾 > > --- > 💬 What does YOUR folder structure look like? Drop it in the comments 👇 --- `#ReactJS` `#FrontendDevelopment` `#WebDevelopment` `#JavaScript` `#CleanCode` `#SoftwareEngineering` `#Programming` `#React` `#CodeNewbie` `#100DaysOfCode` `#FolderStructure` `#TechTips` `#DeveloperLife` `#SoftwareDeveloper` `#LearnToCode` `#OpenSource` `#CodingTips` `#FullStackDeveloper` `#FrontendEngineer` `#UIUXDevelopment` --- **Why this will go viral:** - Opens with a **pain point** every developer feels - Uses **emojis** for scanability on mobile - Ends with a **call to action** (comment + share) that boosts LinkedIn's algorithm - Mix of **broad** (`#WebDevelopment`) and **niche** (`#FolderStructure`) hashtags for maximum reach
To view or add a comment, sign in
-
-
How I Understood Memory Leak in JavaScript One day I wrote this small code: let user = { name: "Siddharth" }; let map = new Map(); map.set(user, "Developer"); user = null; console.log(map); And I thought: 👉 “I removed the user… so memory should be free now.” But I was wrong. 🧠 What actually happened? Even after: user = null; The object was still in memory. Why? Because Map was still holding a reference to it. 👉 JavaScript says: “As long as something is pointing to this object, I won’t delete it.” That’s called a memory leak. 💡 Human way to understand this Imagine: You throw something in the dustbin 🗑️ But someone secretly keeps a copy of it. So it’s not really gone. That’s exactly what Map does here. ⚠️ The problem If this keeps happening in a real app: • Memory keeps increasing 📈 • App becomes slow 🐢 • Eventually crashes 💥 ✅ The fix (cleanup) let user = { name: "Siddharth" }; let map = new Map(); map.set(user, "Developer"); user = null; // Cleanup map.clear(); console.log(map); // Map(0) {} Now: 👉 No reference → memory gets freed 🚀 The lesson I learned 📌 Memory leaks happen when references are not removed 📌 Map keeps strong references 📌 Always clean up unused data Now whenever I use Map, I ask: 👉 Am I removing things I no longer need? Still learning JavaScript the human way. 🚀 #JavaScript #MemoryLeak #WebDevelopment #LearningInPublic #CleanCode #ReactJS #FrontendDevelopment #DeveloperJourney #Performance
To view or add a comment, sign in
-
-
> **Stop guessing where your files go. Here's the React folder structure every developer needs to know. 🗂️** > > After years of messy codebases, late-night debugging sessions, and onboarding nightmares — the secret to a scalable frontend isn't just your code. It's **how you organize it.** > > Here's what each folder does and why it matters: > 📡 **API** — All your backend connections in one place. No more hunting for fetch calls. > 🎨 **Assets** — Static files, images, fonts. Clean and centralized. > 🧩 **Components** — Reusable UI building blocks. Write once, use everywhere. > 🌐 **Context** — Global state without prop drilling chaos. > 📦 **Data** — Static JSON content and constants. > 🪝 **Hooks** — Custom logic extracted and reusable across the entire app. > 📄 **Pages** — One folder per route. Clean, readable, scalable. > 🔄 **Redux** — Advanced state management for complex apps. > ⚙️ **Services** — Business logic and frontend services, separated from UI. > 🛠️ **Utils** — Helper functions that every file in your app will thank you for. > > A well-structured project isn't a luxury — **it's what separates junior from senior developers.** > > Save this. Share it with your team. Your future self will thank you. 💾 > > --- > 💬 What does YOUR folder structure look like? Drop it in the comments 👇 --- **🔥 Hashtags:** `#ReactJS` `#FrontendDevelopment` `#WebDevelopment` `#JavaScript` `#CleanCode` `#SoftwareEngineering` `#Programming` `#React` `#CodeNewbie` `#100DaysOfCode` `#FolderStructure` `#TechTips` `#DeveloperLife` `#SoftwareDeveloper` `#LearnToCode` `#OpenSource` `#CodingTips` `#FullStackDeveloper` `#FrontendEngineer` `#UIUXDevelopment` --- **Why this will go viral:** - Opens with a **pain point** every developer feels - Uses **emojis** for scanability on mobile - Ends with a **call to action** (comment + share) that boosts LinkedIn's algorithm - Mix of **broad** (`#WebDevelopment`) and **niche** (`#FolderStructure`) hashtags for maximum reach
To view or add a comment, sign in
-
-
I wasted 6 hours debugging why my React component was slow. The component had 50 lines of clean code. But it re-rendered 400 times instead of 10. The culprit? A function created inside render. Here's the bug: ```jsx // BUG: Re-renders 400 times unnecessarily function ProjectCard({ project, onLike }) { const handleLike = () => { onLike(project.id) } return ( <div> <h3>{project.name}</h3> <button onClick={handleLike}>Like</button> // NEW function every render </div> ) } ``` Every time ProjectCard renders: - New `handleLike` function created - Child components see it as "changed" - Child components re-render - 400 parent renders = 400 child re-renders The fix: ```jsx import { useCallback } from 'react' function ProjectCard({ project, onLike }) { // handleLike stays the same reference across renders const handleLike = useCallback(() => { onLike(project.id) }, [project.id, onLike]) // Only recreate if dependencies change return ( <div> <h3>{project.name}</h3> <button onClick={handleLike}>Like</button> // Same function instance </div> ) } ``` Now: - `handleLike` reference stays same - Child components don't re-render unnecessarily - 400 renders → 40 renders (10x improvement) **The Pattern I Use:** Rule of thumb for my TypeScript+React projects: - Function passed to child = use useCallback - Computed value passed to child = use useMemo - Everything else = let React handle it **Real example from my portfolio:** In SphereMeet, the user list component was re-rendering 200 times/sec: ```jsx // BEFORE (slow) <UserList users={users} onSelect={(user) => updateSelected(user)} // NEW FUNCTION EVERY RENDER /> // AFTER (fast) const handleUserSelect = useCallback( (user) => updateSelected(user), [] ) <UserList users={users} onSelect={handleUserSelect} /> ``` Performance: 200 re-renders/sec → 2 re-renders/sec (100x!) **When NOT to use useCallback:** ❌ Don't use if: - Function is simple (1 line) - Not passed to child components - Child uses React.memo anyway - Dependency array is longer than function useCallback adds overhead. Only use when necessary. **The Lesson:** Most React performance issues are from: 1. Functions created in render 2. Objects created in render 3. Arrays created in render Fix those three, and React is blazingly fast. Comment "CALLBACK" + like + follow I'll send: → useCallback vs useMemo decision tree → When to use React.memo (and when NOT to) → Profiling tools to find re-render culprits → My real project examples (SphereMeet, Portfolio) (Must be following)
To view or add a comment, sign in
-
🧠 Why React.memo Sometimes Doesn’t Work You wrap your component: const Child = React.memo(({ data }) => { console.log("Rendered"); return <div>{data}</div>; }); You expect it to not re-render. But it still does. Why? 🔍 The real reason React.memo does shallow comparison. So if you pass this 👇 <Child data={{ value: count }} /> 👉 That object is new on every render Even if count didn’t change. ⚠️ Result React sees: {} !== {} 👉 “Props changed” → re-render happens ✅ Fix Memoize the object: const memoData = useMemo(() => { return { value: count }; }, [count]); <Child data={memoData} /> Now the reference stays stable. 🎯 Real Insight React.memo doesn’t prevent re-renders. It only skips them when props are the same reference. 💥 Senior takeaway Most “optimization” fails because of unstable references, not logic. 🧠 Why React.memo Sometimes Doesn’t Work You wrap your component: const Child = React.memo(({ data }) => { console.log("Rendered"); return <div>{data}</div>; }); You expect it to not re-render. But it still does. Why? 🔍 The real reason React.memo does shallow comparison. So if you pass this 👇 <Child data={{ value: count }} /> 👉 That object is new on every render Even if count didn’t change. ⚠️ Result React sees: {} !== {} 👉 “Props changed” → re-render happens ✅ Fix Memoize the object: const memoData = useMemo(() => { return { value: count }; }, [count]); <Child data={memoData} /> Now the reference stays stable. 🎯 Real Insight React.memo doesn’t prevent re-renders. It only skips them when props are the same reference. 💥 Senior takeaway Most “optimization” fails because of unstable references, not logic. #ReactJS #FrontendDeveloper #JavaScript #WebPerformance #SoftwareEngineering #CodingTips #TechCareers #LearningInPublic
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
Great effort