🚀 A React Feature That Looked Simple… But Was Surprisingly Complex While working on a recent React assignment, I implemented a data table with server-side pagination and persistent row selection using React + TypeScript + PrimeReact. At first glance, it seemed like a straightforward task. But once I started building it, I realized how many real-world concepts are involved behind the scenes. Here’s what the feature included: 🔹 Server-Side Pagination Instead of loading all data at once, the table fetches data page-by-page from the API. This keeps the application efficient and scalable. 🔹 Persistent Row Selection Across Pages Users can select rows on one page, navigate to another page, and return later — and their selections remain intact. To achieve this, I stored only row IDs using a Set, avoiding unnecessary data storage and ensuring fast lookup. 🔹 Custom Row Selection Panel I built a custom selection feature using PrimeReact’s OverlayPanel, where users can enter a number to automatically select the first N rows of the current page. 🔹 Avoiding Prefetching Pitfalls The assignment required that we must not fetch additional pages or store other page data. So the logic strictly operates on current page data only, keeping memory usage safe and compliant with the requirements. 🔹 Handling Component Re-rendering Challenges One interesting challenge was that row selection updates didn’t immediately reflect due to DataTable’s internal optimization. Understanding React reconciliation and component keys helped resolve this. 💡 Key Concepts I Reinforced While Building This Server-side pagination Efficient state management using Set React refs (useRef) for controlling UI components Accessibility improvements using aria-label React reconciliation & component re-render behavior Building interactive UI with PrimeReact 🎥 I’ve also recorded a walkthrough of the project, explaining the architecture and logic step-by-step. Would love to hear your thoughts or suggestions! #React #TypeScript #WebDevelopment #FrontendDevelopment #PrimeReact #LearningInPublic #DeveloperJourney #CFBR
More Relevant Posts
-
Slow React vs Fast React — 2.5s to 0.2s Same component. Same data. 2.5 second render time vs 0.2 seconds. The difference is three React optimization patterns most developers skip. -> The slow version Re-fetches data on every single render. No dependency array control on useEffect. No memoization anywhere. The heavy child component re-renders every time the parent updates even when nothing it depends on has changed. The UI thread gets blocked during computation. Result: 2.5 second render. Users wait. Users leave. -> The fast version — three changes First: fetch once on mount. Add an isMounted flag to your useEffect and an empty dependency array. The data fetches once when the component mounts, not on every render. A cleanup function prevents state updates on unmounted components which eliminates memory leak warnings. Second: useMemo for expensive calculations. Wrap any computation that processes large datasets in useMemo with the correct dependencies. The calculation only runs when the data it depends on actually changes — not on every render. const processedData = useMemo(() => data?.map(item => ({...item, result: heavyCalculation(item.value)})), [data] ); Third: React.memo prevents unnecessary child re-renders. Wrap the component in React.memo and it only re-renders when its props actually change. If the parent re-renders for unrelated reasons, the child stays untouched. Result: 0.2 second render. 92 percent faster. Same functionality. These three patterns — controlled useEffect, useMemo, and React.memo — are not advanced React. They are standard React. But most components in production codebases are missing at least one of them. Performance is not something you add at the end. It is something you build correctly from the start. What React performance optimization made the biggest difference in a project you worked on? #React #Performance #JavaScript #FrontendDevelopment #WebDevelopment #Developers #ReactHooks
To view or add a comment, sign in
-
-
Stop using useEffect and useState to fetch data. Seriously. Next.js 16 just made your favorite global state management libraries largely obsolete for basic fetching. Okay, maybe "obsolete" is a strong word. Tools like React Query still have a place for complex client mutations. But for 90% of what we build, the data fetching lifecycle has entirely changed. I recently migrated a dashboard to the new Next 16 pattern, and the amount of boilerplate I deleted was staggering. We used to build fragile client-side pipelines: → Component mounts → useEffect fires → loading state toggles → fetch happens → state updates It was messy, prone to race conditions, and caused terrible network waterfalls. Next 16 formalizes a much cleaner flow. First, you initiate your fetch directly in a Server Component. You don't even have to worry about over-fetching because Next automatically memoizes and dedupes the requests across the tree. Second, instead of awaiting everything at the top and blocking the initial page render, you just pass that raw Promise down to your Client Component as a prop. Finally, you unwrap that Promise inside the Client Component using React's new use() hook. Why is this such a massive upgrade? 🚀 Because passing a Promise from server to client natively integrates with Suspense. When you call use(promise), you don't need to manually track isLoading flags anymore. The UI just waits, gracefully shows your fallback boundary, and renders the data when it's ready. It feels weird at first. Passing an unresolved promise down the component tree feels like breaking a rule we were all taught in React 101. But once you see how it strips away dozens of lines of state management and lifecycle hooks, you realize this is how React was always meant to feel. We are finally moving away from managing the mechanics of fetching, and getting back to just building UI. Have you tried passing promises to the use() hook yet, or are you still holding onto your useEffect blocks? 👇 #Nextjs #React #WebDevelopment
To view or add a comment, sign in
-
🟨 𝗝𝗮𝘃𝗮𝗦𝗰𝗿𝗶𝗽𝘁 𝗗𝗮𝘆 𝟱𝟴: 𝗗𝗮𝘁𝗮 𝗡𝗼𝗿𝗺𝗮𝗹𝗶𝘇𝗮𝘁𝗶𝗼𝗻 𝗶𝗻 𝗥𝗲𝗮𝗰𝘁 (𝗪𝗵𝘆 𝗡𝗲𝘀𝘁𝗲𝗱 𝗦𝘁𝗮𝘁𝗲 𝗗𝗼𝗲𝘀𝗻’𝘁 𝗦𝗰𝗮𝗹𝗲) Ever built a drag & drop UI or complex state… and updates started getting messy? 🤔 🔹 𝗪𝗵𝗲𝗿𝗲 𝗧𝗵𝗶𝘀 𝗛𝗮𝗽𝗽𝗲𝗻𝘀 APIs usually return nested data 👇 But in React, we often transform it into a normalized structure for easier updates & better performance. 🔹 𝗧𝗵𝗲 𝗣𝗿𝗼𝗯𝗹𝗲𝗺 (𝗡𝗲𝘀𝘁𝗲𝗱 𝗦𝘁𝗮𝘁𝗲) const data = [ { id: "todo", cards: [ { id: 1, title: "Fix bug" }, { id: 2, title: "Update UI" } ] }, { id: "progress", cards: [ { id: 3, title: "API work" } ] } ]; 👉 Moving a card = moving full object 😵 👉 Updating = deep nested changes ❌ 👉 Causes unnecessary re-renders in React 🔹 𝗧𝗵𝗲 𝗙𝗶𝘅 (𝗡𝗼𝗿𝗺𝗮𝗹𝗶𝘇𝗮𝘁𝗶𝗼𝗻) const data = { columns: { todo: { id: "todo", cardIds: [1, 2] }, progress: { id: "progress", cardIds: [3] } }, cards: { 1: { id: 1, title: "Fix bug" }, 2: { id: 2, title: "Update UI" }, 3: { id: 3, title: "API work" } } }; 👉 Columns store only IDs 👉 Cards stored once (single source of truth) 🔹 𝗪𝗵𝗮𝘁 𝗖𝗵𝗮𝗻𝗴𝗲𝗱 (𝗥𝗲𝗮𝗰𝘁 𝗣𝗲𝗿𝘀𝗽𝗲𝗰𝘁𝗶𝘃𝗲) Before: • Deep state updates • Re-renders large parts of UI • Hard to maintain After: • Update small pieces of state ✅ • Minimal re-renders (better performance) ⚡ • Cleaner, predictable updates 🔹 𝗞𝗲𝘆 𝗧𝗮𝗸𝗲𝗮𝘄𝗮𝘆 👉 In React, treat state like a database • Store entities once • Reference them using IDs 👉 Drag & Drop = move IDs, not objects 💬 GitHub link in comments. #JavaScript #React #Frontend #Day58 #100DaysOfCode
To view or add a comment, sign in
-
🚀 I stopped manually managing API state in React… and discovered a better way. While building projects, I realized how much time I was spending on: loading states, caching, refetching, and error handling. That’s when I explored TanStack Query. 🧠 What I learned: TanStack Query simplifies server-state management in React. Instead of manually handling API calls with useEffect + useState, it provides: • Automatic caching • Background data refetching • Built-in loading & error states • Request deduplication • Pagination & infinite queries All with minimal code. ⚙️ How it works: Instead of writing multiple states and effects, you can do: • useQuery → fetch data • useMutation → update data Clean. Predictable. Scalable. 📈 Why this matters in real-world projects: In production apps: • API calls increase • State becomes complex • Performance matters TanStack Query helps you: • Reduce boilerplate • Improve performance with caching • Keep UI in sync with server data • Build scalable frontend architecture This is widely used in modern React applications. 💡 Key insight: I realized that not all states are the same. Client state (UI) ≠ Server state (API data) Trying to manage both with useState leads to complexity. TanStack Query solves this separation cleanly. 💡 are you still managing API calls with useEffect, or have you switched to a data-fetching library? #ReactJS #TanStackQuery #FrontendDevelopment #WebDevelopment #SoftwareEngineering #JavaScript
To view or add a comment, sign in
-
-
One of the biggest misconceptions I see: “Signals make lifecycle irrelevant.” No — they just shift it. React controls UI lifecycle (Render → Commit) Signals control data lifecycle (invalidate → recompute → schedule) If you don't respect both boundaries, things break: - tearing - infinite renders - inconsistent updates This article is about drawing that line correctly. #react #webdevs #frontend #javascript #typescript #signals #reactivity
To view or add a comment, sign in
-
I stopped using useEffect for data fetching. Here's why. For years, my React components looked like this: useEffect(() => { setLoading(true); fetch('/api/users') .then(res => res.json()) .then(data => setUsers(data)) .catch(err => setError(err)) .finally(() => setLoading(false)); }, []); Loading state. Error state. Race conditions. Cleanup functions. Stale closures. Every. Single. Component. Then I switched to React Query (TanStack Query) and deleted 40% of my state management code overnight. Here's what changed: → No more loading/error/data useState triplets → Automatic caching — same data across 10 components, 1 network request → Background refetching — users always see fresh data without spinners → Race condition handling — built in, not bolted on → Retry logic — automatic, configurable, zero custom code But here's what most tutorials won't tell you: React Query doesn't replace ALL useEffect calls. It replaces the ones you should never have written in the first place. useEffect is still perfect for: • Subscriptions (WebSocket, event listeners) • DOM synchronization • Third-party library integration The mistake is using useEffect as a "fetch on mount" hook. That was always a workaround, not a pattern. In my TypeScript projects, I enforce this with a simple ESLint rule: no fetch() inside useEffect. If you're fetching data, use a query hook. Period. The result? Components that are 50% shorter, easier to test, and actually work correctly with React 18+ concurrent features. What's your go-to data fetching approach in React? Still useEffect, or have you moved on? #React #TypeScript #ReactQuery #TanStackQuery #WebDevelopment #JavaScript #DeveloperProductivity #CleanCode
To view or add a comment, sign in
-
-
🚀 Day 15/30 – Lifting State Up (Deep Dive) Struggling to sync data between components? 🤔 Today I learned one of the most important React concepts ⚡ 👉 Lifting State Up Today I learned: ✅ Move state to the closest common parent ✅ Share data via props ✅ Maintain single source of truth 💻 Real Example: function Parent() { const [name, setName] = useState(""); return ( <> </> ); } function ChildInput({ name, setName }) { return ( <input value={name} onChange={(e) => setName(e.target.value)} /> ); } function ChildDisplay({ name }) { return Hello {name}; } 🔥 What actually happens: 1️⃣ User types in ChildInput 2️⃣ setName updates parent state 3️⃣ Parent re-renders 4️⃣ ChildDisplay gets updated value 👉 Both components stay perfectly in sync 💡 Wrong Approach (Common Mistake): ❌ Separate state in each component function ChildA() { const [name, setName] = useState(""); } function ChildB() { const [name, setName] = useState(""); } 👉 This creates inconsistent UI 😵 ⚡ Real Use Cases: Shared form data Cart state across components Filters + product list sync ⚡ Advanced Insight: React enforces one-way data flow 👉 Parent → Child (via props) 🔥 Key Takeaway: If multiple components depend on same data → lift it up. Are you still duplicating state or managing it correctly? 👇 #React #StateManagement #FrontendDevelopment #JavaScript #WebDevelopment
To view or add a comment, sign in
-
-
I started a new enterprise project and quickly ran into a familiar problem: most business components (datagrids and other) are either heavily limited in their community versions or priced way beyond what they actually offer. (Sometimes it makes sense - but most of the time, it doesn’t.) At some point, it became easier to build my own solution than to keep compromising - both for this project and future ones. That’s how dv-datagrid was born - a fully open-source (MIT) data grid for Angular that covers real production needs: sorting, filtering (text, numbers, dates, sets), pagination server-side data support column resizing with auto-fit row selection (single/multi) row expansion Excel export custom cell renderers fully typed API with Angular Signals theming support No license keys. No “pay to unlock”. No surprises. Built with Angular 21 using standalone components and a signals-first approach - modern, lightweight, and tree-shakeable. 📦 npm: npm install dv-datagrid 🔗 GitHub: https://lnkd.in/dwhYziz4 🌐 Demo: https://lnkd.in/dxydcSHG This is just the beginning. On the roadmap: more features based on community feedback a companion .NET library to simplify integration with Entity Framework - making server-side sorting, filtering, and pagination almost zero-boilerplate If you’ve been frustrated with the Angular data grid ecosystem, give dv-datagrid a try 🙂 #Angular #OpenSource #DotNet #WebDevelopment #Frontend #TypeScript #MIT
To view or add a comment, sign in
-
-
A common React anti-pattern I still see everywhere: Fetching critical data (like user session) inside useEffect. useEffect(() => { fetch("/api/session").then(...) }, []) It looks harmless, but it introduces a lot of problems. 1. Double fetches in React Strict Mode In development, React intentionally runs effects twice. Your session endpoint gets called twice. Many teams only discover this later when logs look strange or rate limits get hit. 2. Rendering before auth state exists The component renders before the fetch completes. That means: • UI flickers between logged-out and logged-in states • Protected components may render briefly • Layout shifts happen Your app becomes dependent on loading states everywhere. 3. Waterfall data loading If session is fetched in useEffect, other components that depend on the user must wait for it. This creates a request chain like: render → fetch session → render again → fetch user data → render again Now your first paint becomes slower. 4. Hydration problems in SSR In frameworks like Next.js: • Server render doesn’t know the session • Client fetches it after mount • Server and client output differ Result: hydration mismatch or UI flicker. 5. Unnecessary re-fetching If the component remounts or dependencies change, the session call runs again. Auth data should usually be stable, not repeatedly fetched by components. 6. Harder caching and global state Auth/session is application-level state, not component-level state. Putting it in useEffect spreads that responsibility across components instead of centralizing it. ⸻ Better approaches: • Fetch session on the server (SSR / middleware) • Use a global cache layer (React Query / SWR) • Use framework auth providers • Or resolve session before rendering the app Session is foundational state. Treat it like infrastructure, not like a side effect. There’s a reason many large dashboards moved away from this pattern after running into production issues. Even small architectural decisions like this can cascade into outages. #reactjs #architecture #sideeffects
To view or add a comment, sign in
-
-
A component that owns its own data is a component you cannot reuse. This is the pattern I see repeatedly in React and Next.js codebases: a list of services, team members, or project entries hardcoded directly inside the component that renders them. It works fine until you need the same data somewhere else — then you either duplicate it or refactor under pressure. The fix is a clean separation between data and presentation. Data in the component — the problem // components/ServicesList.tsx export function ServicesList() { const services = [ { title: 'React Development', price: '€85/hr' }, { title: '.NET Backend', price: '€90/hr' }, ]; return <ul>{services.map(s => <li key={s.title}>{s.title}</li>)}</ul>; } This component cannot be tested without rendering it. The data cannot be used anywhere else without copying it. Changing a price means finding the component first. Data in lib/ — the solution // lib/services.ts export const services = [ { title: 'React Development', price: '€85/hr' }, { title: '.NET Backend', price: '€90/hr' }, ]; // components/ServicesList.tsx import { services } from '@/lib/services'; export function ServicesList() { return <ul>{services.map(s => <li key={s.title}>{s.title}</li>)}</ul>; } Now the data is importable by any component, any page, any utility function, or any test. The component is a pure rendering function. Changing the data means editing one file with no component knowledge required. This pattern scales to typed data structures, derived values, and server-side data fetching. The component stays clean. The data stays accessible. Both are independently testable and maintainable. Separation of concerns is not an architecture principle for large teams. It is a habit that pays off the first time you need the same data in two places. #react #nextjs #typescript #frontend #softwaredevelopment #webdevelopment #architecture
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