I've seen 100+ React codebases. The ones that scale? They all share ONE thing in common. Their components are dumb. Beautifully, embarrassingly dumb. Here's what most developers get wrong: They dump everything into one component — fetching, loading states, error handling, business logic, AND the UI. It works on day 1. By month 3, nobody wants to touch it. The fix? Brutal separation of logic and presentation. Here's the pattern that changed how I build: ───────────────────────── ❌ THE MESSY WAY (what 80% of teams ship) function UserProfile({ id }) { const [user, setUser] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { fetch(`/api/users/${id}`) .then(res => res.json()) .then(data => { setUser(data); setLoading(false) }) .catch(err => { setError(err); setLoading(false) }) }, [id]) if (loading) return <Spinner /> if (error) return <ErrorBanner /> return <div>...</div> // UI buried under logic } This is a ticking time bomb. Add caching? Retry logic? Stale-while-revalidate? This component explodes. ───────────────────────── ✅ THE CLEAN WAY (production-ready) LAYER 1 → API (pure function, zero React) // api/users.ts export const fetchUser = (id) => fetch(`/api/users/${id}`).then(res => res.json()) LAYER 2 → Custom Hook (logic lives here) // hooks/useUser.ts export function useUser(id) { return useQuery({ queryKey: ['user', id], queryFn: () => fetchUser(id), staleTime: 5 * 60 * 1000, }) } LAYER 3 → Component (pure presentation) // components/UserProfile.tsx export function UserProfile({ id }) { const { data, isLoading, error } = useUser(id) if (isLoading) return <Skeleton /> if (error) return <ErrorBanner /> return <div>{data.name}</div> } ───────────────────────── See what happened? → The component doesn't KNOW how data is fetched → Swap React Query for SWR tomorrow? Zero UI changes → Want to reuse this data on 3 other pages? useUser(id) — done → Testing? Each layer is independently testable This isn't theory. This is how teams at scale actually survive. The rules I live by: 1️⃣ If your component has more than 2 hooks, extract logic into a custom hook 2️⃣ API calls never live inside components 3️⃣ Components should only know about loading, data, and error — nothing else 4️⃣ Custom hooks are your business logic boundary React Query + Custom Hooks isn't just a pattern. It's the difference between code you maintain and code you rewrite. Start separating. Your future self will thank you. #React #ReactQuery #CleanCode #WebDevelopment #Frontend #JavaScript #SoftwareEngineering #TechLeadership #DevOps #CareerGrowth
Separate Logic from UI with React Query and Custom Hooks
More Relevant Posts
-
React 19 - new game-changer: the use hook! If you're tired of writing the same useEffect + useState boilerplate for every single API call, this one's for you. Here’s why your code is about to get a whole lot cleaner. 🛑 The "Old" Way (Boilerplate Central) We’ve all been there. You want to fetch data, so you: Initialize state (data, loading, error). Trigger useEffect. Handle the async promise. Update state... and hope you didn't forget the cleanup! ✨ The "React 19" Way (Clean & Declarative) With the new use hook, you can "unwrap" promises directly in your render. No more manual loading states—React handles the "waiting" part using Suspense. JavaScript import { use } from 'react'; // 1. Your standard fetch function const fetchUserData = fetch('/api/user').then(res => res.json()); function UserProfile() { // 2. Just 'use' it! const user = use(fetchUserData); // 3. No 'if (loading)' needed here! return <h1>Welcome back, {user.name}!</h1>; } 💡 Why developers love it: Conditional Hooks: You can actually use use inside if statements or loops. (Yes, really!) Bye-bye Boilerplate: It works hand-in-hand with <Suspense> for loading and <ErrorBoundary> for errors. Readable Code: Your component focuses on the UI, not the plumbing. Is useEffect dead? Not quite—but for data fetching, the use hook is definitely the new favorite child. 👶 Which should you use? Go with use if you are starting a new React 19 project and want a "native" feel with less code. It’s perfect for simple data fetching and working with Context. Stick with useEffect if you are maintaining an older codebase or need to synchronize with non-React systems (like a WebSocket or a manual DOM library). ** New Era ** Combining the use hook with an ErrorBoundary and Suspense is the "Holy Trinity" of React 19 data fetching. It moves the complexity out of your component logic and into your component structure. Check the attached image for more details. The "Safety Net" Pattern Think of Suspense as your Loading Spinner and ErrorBoundary as your Catch-All for when the API goes down. Why this is a massive upgrade: No "Jank": In the old useEffect way, the component would render once with data = null, then re-render when the data arrived. This often caused layout shifts. With use, the component doesn't even finish its first render until the data is ready. Centralized Logic: If you have 10 components fetching data, you don't need 10 if (loading) checks. You just wrap them all in one high-level Suspense boundary. Better DX (Developer Experience): Your UserProfile component is now "pure." It doesn't care about fetch logic; it just assumes the data is there when it runs. Pro Tip: Remember that React 19 makes this pattern even cleaner. You can now pass that ref down into the same Suspense tree without needing forwardRef. Stay tuned for my upcoming post regarding useRef. #React19, #ReactJS, #useHook, #ReactHooks,#JavaScript, #CleanCode, #SoftwareDevelopment, #Frontend, #ModernWeb,#SystemDesign
To view or add a comment, sign in
-
-
React Components: Functional vs Class (With Lifecycle Explained) In React, components are the core building blocks of any application. There are two main types: - Functional Components - Class Components * Functional Components: Functional components are simple JavaScript functions that return JSX. Key Features: - Cleaner and shorter syntax - Use Hooks (useState, useEffect) - Preferred in modern React - Easier to test and maintain Example: import React, { useState, useEffect } from "react"; function Counter() { const [count, setCount] = useState(0); useEffect(() => { console.log("Component Mounted or Updated"); return () => { console.log("Component Unmounted"); }; }, [count]); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); } Lifecycle in Functional Components (Using Hooks) Functional components handle lifecycle using the useEffect Hook. * Class Components: Class components are ES6 classes that extend React.Component. Key Features: - Use this.state - Have built-in lifecycle methods - More boilerplate Example: import React, { Component } from "react"; class Counter extends Component { constructor(props) { super(props); this.state = { count: 0 }; } componentDidMount() { console.log("Mounted"); } componentDidUpdate() { console.log("Updated"); } componentWillUnmount() { console.log("Unmounted"); } render() { return ( <div> <p>Count: {this.state.count}</p> <button onClick={() => this.setState({ count: this.state.count + 1 })}> Increment </button> </div> ); } } Lifecycle in Class Components: Mount: componentDidMount() Update: componentDidUpdate() Unmount: componentWillUnmount() Today, Functional Components + Hooks = Standard Practice in React. Class components are still supported, but mostly used in older projects. Which lifecycle approach do you find easier — Hooks or Class methods? #React #FrontendDevelopment #WebDevelopment #JavaScript #Programming #DeepDivine
To view or add a comment, sign in
-
Are your React components becoming difficult to maintain and test? A common pitfall in growing React applications is coupling business logic too tightly with UI rendering. This leads to bloated components that are hard to reuse and even harder to debug. The solution often lies in better Separation of Concerns, specifically the Container/Presentational Pattern. While React Hooks have changed how we implement this, the underlying architectural principle remains vital for writing clean, scalable frontend code. I’ve written a deep dive into this pattern, covering: ✅ Clear definitions of "Smart" (Container) vs. "Dumb" (Presentational) components. ✅ Visual examples of the data flow. ✅ Practical code scenarios. ✅ How to adapt this pattern using modern React Hooks. Check out the full article to improve your component structure today. https://lnkd.in/gZkVwzeF #ReactJS #JavaScript #FrontendDevelopment #WebDevelopment #ReactDeveloper #TypeScript
To view or add a comment, sign in
-
🚀 Controlled vs Uncontrolled Components in React When handling forms in React, we often use either Controlled or Uncontrolled components. The difference is about who manages the input data. 🔵 Controlled Component A controlled component is an input field whose value is managed by React state. 👉React becomes the single source of truth. Example: import { useState } from "react"; function ControlledForm() { const [name, setName] = useState(""); return ( <input type="text" value={name} onChange={(e) => setName(e.target.value)} /> ); } Here ●'useState' stores the input value. ●Every time the user types, 'onChange' updates the state. ●The input always displays the value from React state. ✅ Best for validation, dynamic UI updates, and complex forms. 🟠 Uncontrolled Component An uncontrolled component stores its data in the DOM, not in React state. 👉 React accesses the value only when needed using 'useRef'. Example: import { useRef } from "react"; function UncontrolledForm() { const nameRef = useRef(); const handleSubmit = () => { alert(nameRef.current.value); }; return ( <> <input type="text" ref={nameRef} /> <button onClick={handleSubmit}>Submit</button> </> ); } Here ●The input manages its own value internally. ●'useRef' is used to access the value when the button is clicked. ●React does not track every keystroke. ✅ Best for simple forms or quick implementations. 💡 Difference: ■Controlled → React controls the data. ■Uncontrolled → DOM controls the data. Understanding this concept helps in building cleaner, more predictable, and scalable React applications. #ReactJS #FrontendDevelopment #JavaScript #WebDevelopment #ReactLearning
To view or add a comment, sign in
-
-
🤔 Ever noticed how some functions don’t do the work themselves… they coordinate other functions? That’s the whole idea behind Higher-Order Functions (HOFs) in JavaScript. 🧠 JavaScript interview question What are higher-order functions? ✅ Short answer A higher-order function is a function that: • takes a function as an argument, and/or • returns a function as the result 🔍 A bit more detail HOFs help you separate: • what to do (your callback logic) from • how to do it (iteration, timing, caching, event handling) That’s why things like map, filter, reduce, event handlers, middleware, and async helpers feel so clean. You pass small “what” functions, and the HOF handles the “how”. 💻 Examples // classic HOFs: map / filter / reduce const nums = [1, 2, 3, 4]; const squares = nums.map(n => n * n); const evens = nums.filter(n => n % 2 === 0); const sum = nums.reduce((acc, n) => acc + n, 0); // returns a function: once() function once(fn) { let called = false; let value; return function (...args) { if (!called) { called = true; value = fn.apply(this, args); } return value; }; } const init = once(() => "Initialized!"); init(); // "Initialized!" init(); // "Initialized!" (doesn't run again) ⚛️ React tie-in React is full of HOF patterns: • memo(Component) returns a new optimized component • event handlers are functions passed into other functions (onClick={() => ...}) • custom hooks often return functions (useMutation, useCallback patterns) 🚫 Common misconceptions • HOFs are only for arrays Nope. Any time you pass or return a function, you’re in HOF land. • Currying and partial application are the same Currying transforms fn(a,b) into fn(a)(b). Partial application “pre-fills” some args. • HOFs are always slower Usually the readability and composability wins. Measure before optimizing. #javascript #frontend #webdevelopment #reactjs #programming #softwareengineering #codinginterview #learninpublic
To view or add a comment, sign in
-
Bug fixed — checkbox persistence in my React Todo app Problem: after checking a todo and reloading the page, the checkbox would appear unchecked. Root cause: the checked prop in the checkbox expects a boolean, but localStorage sometimes contained "true" / "false" (strings) or inconsistent shapes. That made the UI show wrong values after reload. Fix (two parts): Normalize stored data on init — use a lazy useState initializer to read from localStorage once and convert "true"/"false" strings to booleans safely. Update state immutably — toggle using map() and spread so the isCompleted flag is correctly flipped and persisted. Key snippets: // Initialize todos from localStorage (lazy initializer) const [todos, setTodos] = useState(() => { try { const raw = localStorage.getItem('todos'); if (!raw) return []; const parsed = JSON.parse(raw); return parsed.map(t => ({ id: t.id ?? uuidv4(), todo: typeof t.todo === 'string' ? t.todo : '', // normalize isCompleted: boolean or "true"/"false" isCompleted: typeof t.isCompleted === 'boolean' ? t.isCompleted : t.isCompleted === 'true', })); } catch { return []; } }); // Toggle handler (immutable update) const handleCheckbox = id => { setTodos(prev => prev.map(item => item.id === id ? { ...item, isCompleted: !item.isCompleted } : item )); }; // Persist whenever todos change useEffect(() => { localStorage.setItem('todos', JSON.stringify(todos)); }, [todos]); Result: after checking a todo it stays checked after reload ✅ Learning: !!value coerces to boolean for quick UI checks (checked={!!item.isCompleted}), but the real fix is normalizing your stored data on load so you don’t rely on ad-hoc coercion. Thoughts welcome! #react #javascript #webdev #frontend #100DaysOfCode
To view or add a comment, sign in
-
ReactJS performance optimization's points- 1. Prevent Unnecessary Re-renders Use React.memo and useMemo: Memoize components and expensive calculations to avoid redundant rendering. Use useCallback: Memoize event handlers passed as props. Pure Components: Ensure components only re-render when props/state change. 2. Optimize State Management Lift state only when necessary: Avoid global state for local concerns. Use Context carefully: Overuse can trigger deep re-renders; prefer libraries like Zustand or Jotai for fine-grained updates. Batch updates: React automatically batches updates, but ensure async state changes are grouped efficiently. 3. Bundle Size Reduction Code Splitting: Use dynamic imports (React.lazy, Suspense) to load components only when needed. Tree Shaking: Ensure unused code is removed via Webpack/Rollup. Multiple Chunk Files: Split vendor and app code for faster caching. 4. Rendering & Loading Optimizations Lazy Loading Images: Load images only when visible in the viewport. Virtualized Lists: Use libraries like react-window or react-virtualized for large datasets. Server-Side Rendering (SSR): Improves initial load and SEO. Use CDN for assets: Faster delivery of static files. 5. Event Handling Throttling & Debouncing: Prevent performance bottlenecks from frequent events (scroll, resize, input). Web Workers: Offload heavy computations to background threads. 6. Modern React Features (React 19+) Automatic Memoization via React Compiler: Reduces developer overhead in optimizing re-renders. useTransition Hook: Improves responsiveness by deferring non-urgent updates. 7. Web Workers for Heavy Computations JavaScript is single-threaded. Heavy computations block the UI thread, making your app unresponsive. Web Workers move computations to background threads. 8. Memory Leak Prevention Memory leaks slowly degrade React app performance over time. Users don't notice immediately, but after 10-15 minutes, the app becomes sluggish and eventually crashes. 9. Performance Monitoring and Profiling You can't optimize what you don't measure. React DevTools Profiler and Chrome DevTools give you the insights needed to identify bottlenecks. ⚠️ Common Pitfalls to Avoid Bloated bundles: Importing entire libraries instead of specific modules. Overusing Context: Causes unnecessary re-renders across the app. Ignoring production mode: Always build with NODE_ENV=production for optimized React behavior. #ReactJS #ReactPerformanceoptimization
To view or add a comment, sign in
-
This single line actually touches many core React + Redux concepts. I’ll break it down slowly, deeply, and practically, the way interviewers love to hear it explained. 🔹 The Code Line const { loading, error, resetPasswordDone } = useSelector( (state) => state.authState ); 🧠 BIG PICTURE (What is happening?) You are reading data from the Redux store and subscribing this component to changes in the authState slice. Whenever authState changes → this component re-renders automatically. 🧩 CONCEPTS INVOLVED (High-level) This line involves 6 core concepts: Redux Store Redux Slice Global State useSelector Hook JavaScript Destructuring React Re-rendering Let’s go step by step 👇 1️⃣ Redux Store (Global State Container) Redux has one central store: store = { authState: { loading: false, error: null, resetPasswordDone: false, user: null, isAuthenticated: false }, productState: {...}, cartState: {...} } 👉 This store lives outside React 👉 Any component can read data from it 2️⃣ authState (Redux Slice) authState is a slice of the Redux store. Created using: createSlice({ name: "auth", initialState: { loading: false, error: null, resetPasswordDone: false, }, }) So this part: state.authState means: “Give me the authentication-related state from the Redux store.” 3️⃣ useSelector Hook (Bridge between React & Redux) useSelector((state) => state.authState) What useSelector does: Reads data from Redux store Subscribes the component to that data Re-renders component when data changes 📌 Think of it as: useState, but for Redux global state How it works internally: Redux store updates useSelector checks if selected data changed If changed → component re-renders ✔ Efficient ✔ Automatic ✔ No manual listeners 4️⃣ Arrow Function (state) => state.authState (state) => state.authState state = entire Redux store You are selecting only the authState slice Equivalent to: const fullStore = state; return fullStore.authState; 5️⃣ JavaScript Destructuring (Very Important) Instead of writing: const authState = useSelector((state) => state.authState); const loading = authState.loading; const error = authState.error; const resetPasswordDone = authState.resetPasswordDone; const { loading, error, resetPasswordDone } = ... ✅ Cleaner ✅ Shorter ✅ Industry standard 6️⃣ What Each Variable Represents 🔄 loading loading === true ➡ API request is in progress Used for: disabled={loading} {loading ? "Updating..." : "Set Password"} ❌ error error === "Token expired" ➡ Backend or network error Used for: toast.error(error); dispatch(clearAuthError()); ✅ resetPasswordDone resetPasswordDone === true ➡ Password reset was successful Used for: navigate("/login"); 🔁 FULL DATA FLOW (Inter User submits form ↓ dispatch(resetPassword) ↓ Redux thunk starts ↓ loading = true ↓ API call to backend ↓ SUCCESS ↓ resetPasswordDone = true ↓ useSelector detects change ↓ Component re-renders ↓ useEffect runs ↓ Redirect to login
To view or add a comment, sign in
-
🔁 Javascript Conditions and Loops 🔹 Why Conditions & Loops Matter - They help your program make decisions - They let your code repeat tasks - Without them, JavaScript is useless for logic Real use cases: Login validation, Form checks, Iterating data from APIs 🧠 Conditions (Decision Making) Conditions run code only when a condition is true. ✅ if statement let age = 20; if (age >= 18) { console.log("Eligible to vote"); } - Code runs only if condition is true 🔁 if–else if (age >= 18) { console.log("Adult"); } else { console.log("Minor"); } - Two paths • One always runs 🔂 else if let marks = 75; if (marks >= 90) { console.log("Grade A"); } else if (marks >= 70) { console.log("Grade B"); } else { console.log("Grade C"); } - Multiple conditions checked in order 🔀 switch statement Used when checking one value against many cases. let day = 2; switch (day) { case 1: console.log("Monday"); break; case 2: console.log("Tuesday"); break; default: console.log("Invalid day"); } ⚠️ Always use break to avoid fall-through. 🔁 Loops (Repetition) Loops run code multiple times. 🔹 for loop Best when number of iterations is known. for (let i = 1; i <= 5; i++) { console.log(i); } 🔹 while loop Runs while condition is true. let i = 1; while (i <= 3) { console.log(i); i++; } 🔹 do–while loop Runs at least once. let i = 5; do { console.log(i); i++; } while (i < 3); 📦 Loop Control Keywords - break → stops loop - continue → skips iteration for (let i = 1; i <= 5; i++) { if (i === 3) continue; console.log(i); } ⚠️ Common Beginner Mistakes - Infinite loops - Missing break in switch - Using == instead of === - Wrong loop condition 🧪 Mini Practice Task - Check if a number is even or odd - Print numbers from 1 to 10 - Print only even numbers - Use switch to print day name ✅ Mini Practice Task – Solution 🔁 🟦 1️⃣ Check if a number is even or odd let num = 7; if (num % 2 === 0) { console.log("Even number"); } else { console.log("Odd number"); } ✅ Uses modulus operator • Remainder 0 → even • Otherwise → odd 🔢 2️⃣ Print numbers from 1 to 10 for (let i = 1; i <= 10; i++) { console.log(i); } 🔁 3️⃣ Print only even numbers from 1 to 10 for (let i = 1; i <= 10; i++) { if (i % 2 === 0) { console.log(i); } } 📅 4️⃣ Use switch to print day name let day = 3; switch (day) { case 1: console.log("Monday"); break; case 2: console.log("Tuesday"); break; case 3: console.log("Wednesday"); break; case 4: console.log("Thursday"); break; case 5: console.log("Friday"); break; default: console.log("Invalid day"); }
To view or add a comment, sign in
-
🤔 Ever imported a package and got hit with one of these? ReferenceError: require is not defined Cannot use import statement outside a module “Why does this library work in Node but not in the browser?” That’s almost always ESM vs CommonJS. 🧠 JavaScript interview question What’s the difference between ESM and CommonJS, and when would you use each? ✅ Short answer CommonJS (CJS) uses require() / module.exports and loads modules at runtime (Node’s classic system). ES Modules (ESM) uses import / export, is static by default, and enables better tooling like tree-shaking. 🔍 The real differences that matter in real projects 📦 Syntax CJS: const x = require("x") + module.exports = ... ESM: import x from "x" + export ... ⏱️ When it resolves CJS resolves while your code runs → can do if (...) require(...) ESM is statically analyzed (imports are at the top level) → bundlers can optimize it 🌳 Tree-shaking ESM: ✅ easy to remove unused exports (webpack/vite/rollup love this) CJS: ❌ harder because exports can be dynamic 🔁 Interop gotchas Importing CJS in ESM can lead to “default export weirdness” In Node, ESM often needs "type": "module" or .mjs 💻 Tiny examples CJS // math.js function add(a, b) { return a + b; } module.exports = { add }; // index.js const math = require("./math"); console.log(math.add(2, 3)); ESM // math.mjs export function add(a, b) { return a + b; } // index.mjs import { add } from "./math.mjs"; console.log(add(2, 3)); ⚛️ React / Next.js practical note Modern React apps + Next.js code is ESM-first (bundlers + tree-shaking). But some Node tooling / older libs still ship CJS → you’ll see mixed ecosystems in monorepos. 🎯 Rule of thumb ✅ Choose ESM for modern apps and libraries. ✅ Use CJS when you must support older Node setups or legacy packages. #JavaScript #Frontend #WebDevelopment #NodeJS #React #Nextjs #TypeScript #CodingInterview
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