WHY STORING FILTERS IN useState IS A BAD IDEA : Filters look like simple UI state. But treating them as local state creates real problems in production apps. What usually happens: Filters are stored using useState Example: • search query • category • price range • page number It works… until users actually use the app. The real problems: 👉 Refresh the page → All filters reset 👉 Copy the URL → No filters included 👉 Share the link → Other user sees different data 👉 Navigate back/forward → State is inconsistent 👉 This breaks user experience in real products The core mistake: Treating filters as UI state But filters are NOT just UI 👉 They represent the current view of data That means: They should live in the URL The correct approach: 👉 URL = Single Source of Truth Instead of: useState → local state Use: URL query params → global state How this works in real apps (Next.js): Use built-in routing tools • useSearchParams() → read filters from URL • useRouter() → update query params Example URL: ?search=laptop&category=electronics&page=2 👉 This URL fully describes the UI state Why this is powerful: • Refresh safe → state persists • Shareable → exact same view • Bookmark friendly • SEO friendly (important for Next.js apps) • Works naturally with browser navigation Real production pattern: When filters change • Update URL params • Reset pagination (page = 1) • Trigger data refetch Where TanStack (React Query) fits: This is where things become clean. Query key depends on URL params Example: ["products", search, category, page] 👉 When URL changes → query key changes → auto refetch No manual state syncing needed Clean architecture flow: URL → Source of truth ↓ React reads params ↓ TanStack Query fetches data ↓ UI renders 👉 No duplicate state 👉 No inconsistencies Important mindset shift: The URL is not just navigation It is: • State • Memory • Shareable context Final Insight: useState is for temporary UI state (not for data that defines the page) If the state affects: • data fetching • navigation • sharing 👉 It belongs in the URL Once this pattern is clear → frontend architecture becomes much cleaner and predictable #ReactJS #NextJS #TanStackQuery #Frontend #WebDevelopment #SystemDesign
Storing Filters in useState: A Bad Idea for Production Apps
More Relevant Posts
-
Enhancing User Experience with Infinite Scroll & TanStack Query I recently explored advanced data-fetching patterns in React to build a seamless, production-grade product feed. While standard pagination works, Infinite Scroll provides a much more fluid experience for modern web applications. The Technical Breakdown: TanStack Query (React Query): Leveraged the power of useInfiniteQuery to manage complex paginated states. It elegantly handles the "loading more" state, caching, and data synchronization without manual boilerplate. The Logic: Implemented getNextPageParam to calculate the next data chunk based on total records and currently loaded items. This ensures the app knows exactly when to stop fetching and avoids redundant API calls. Infinite Scroll + Manual Trigger: Integrated a scroll listener with window.innerHeight to auto-fetch content as the user reaches the bottom, while maintaining a "Load More" button fallback for accessibility and user control. Async/Await & Promises: Deep-dived into how React Query abstracts the complexity of Promises. Instead of manually managing useState and useEffect for every API call, TanStack Query waits for the Promise to resolve and provides clean, synced data directly. Key Takeaway: Efficient state management isn't just about fetching data—it's about how you deliver it. Using a nested mapping strategy over data.pages allowed for a smooth UI transition as the product list grows. Stack: React.js, TanStack Query, Axios, Tailwind CSS. Devendra Dhote #ReactJS #WebDevelopment #TanStackQuery #FrontendEngineering #CleanCode #FullStackDeveloper
To view or add a comment, sign in
-
🚀 How to Optimize API Calls in React (Properly Explained) Many React apps become slow not because of UI… But because of inefficient API calls ⚠️ Let’s fix that 👇 ❌ Without Optimization • Multiple unnecessary API calls • Same data fetched again & again • Slow UI & poor performance • High server load ✅ With Optimization • Only required API calls • Cached & reused data • Faster UI response • Better user experience 🧠 Best Practices to Optimize API Calls 🧩 1. Fetch Only What You Need → Avoid large payloads ✔ Request specific fields only ⚡ 2. Use Caching (React Query / SWR) → Don’t refetch same data ✔ Automatic caching & background updates 🔁 3. Avoid Duplicate Requests → Store data globally (context/store) ✔ Prevent unnecessary API calls ⌛ 4. Debounce & Throttle Inputs → Reduce API calls while typing ✔ Perfect for search & filters 📄 5. Pagination / Infinite Scroll → Load data in chunks ✔ Better performance & UX ❌ 6. Cancel Unnecessary Requests → Abort old requests when new ones trigger ✔ Saves bandwidth 🔗 7. Batch API Requests → Combine multiple calls into one ✔ Faster & efficient 🎯 8. Conditional Fetching → Call API only when needed ✔ Avoid useless calls 🔄 9. Background Refetching → Keep UI fast + data fresh ✔ Show cached data instantly ⚡ 10. Use Proper HTTP Methods → Follow REST best practices ✔ Efficient API design 🔥 Real Impact ✔ Faster applications ✔ Better UX ✔ Reduced server cost ✔ Scalable frontend 🧠 Golden Rule: 👉 Don’t fetch more. Fetch smarter. 💬 Which technique improved your app performance the most? #React #Frontend #WebPerformance #API #JavaScript #WebDevelopment #Coding #SoftwareEngineering
To view or add a comment, sign in
-
-
💡 One of the most common interview questions: “𝗛𝗼𝘄 𝗱𝗼 𝘆𝗼𝘂 𝗿𝗲𝗻𝗱𝗲𝗿 𝗮 𝗹𝗮𝗿𝗴𝗲 𝗹𝗶𝘀𝘁 𝗼𝗳 𝗱𝗮𝘁𝗮?” Most people immediately think of frontend optimizations like: • memoization • lazy loading But there’s a backend angle too 👇 📄 Traditional approach: Page-based pagination • send page + limit • use skip on database • return data Works well for: ✅ small to medium datasets ✅ quick implementation ⚠️ But what happens when data grows? Imagine: • 100,000 records • 100 per page → 1000 pages Now think about the UX 🤯 • endless page numbers • poor navigation • slower queries with large skips 🚀 Better approach: Cursor-based pagination Instead of page numbers, we use a cursor (usually last item id). How it works: • send last fetched item id • query next set using > (greater than)/ <(less than) condition • return next batch ✨ Benefits: ✅ smooth infinite scrolling ✅ better performance on large datasets ✅ no large skip operations ✅ improved user experience 🖥️ On frontend: We can use Intersection Observer to detect when user reaches the bottom → trigger next API call. ⚡ Simple idea, but widely used in: • social media feeds • e-commerce apps • search results Sometimes the right solution is not just optimizing rendering… It’s choosing the right 𝗱𝗮𝘁𝗮 𝗳𝗲𝘁𝗰𝗵𝗶𝗻𝗴 𝘀𝘁𝗿𝗮𝘁𝗲𝗴𝘆. #javascript #webdevelopment #systemdesign #backend #frontend
To view or add a comment, sign in
-
-
🚀 Excited to share my latest project — Custom Dashboard Builder! I built a full-stack application that lets users create, configure, and save personalized dashboards — all through a drag-and-drop interface. 🔧 What it does: • Drag & resize widgets onto a live grid canvas • Visualize data using Bar, Line, Area, Pie & Scatter charts • Display KPI cards with Count, Sum & Average aggregations • Sort, filter & paginate data with interactive tables • Auto-align layouts with one click • Dashboards persist across sessions via MongoDB • Fully responsive across all screen sizes 🛠️ Tech Stack: Frontend → React 19, Vite, TailwindCSS 4, Recharts, React Grid Layout Backend → Node.js, Express, Prisma ORM, MongoDB This project pushed me to think deeply about component architecture, state management across a dynamic widget system, and designing a smooth drag-and-drop UX from scratch. Check it out 👉 https://lnkd.in/gnZyUx5y #React #NodeJS #MongoDB #FullStack #WebDevelopment #OpenSource #BuildInPublic
To view or add a comment, sign in
-
Does your React component still have a 'useEffect' with a 'fetch' inside? You're probably creating a worse UX and more complex code unnecessarily. The classic pattern of 'useState' + 'useEffect' for fetching data is the cause of many problems: ❌ Waterfalls de requests. ❌ Loading spinners that cause CLS (Cumulative Layout Shift). ❌ Boilerplate of 'isLoading', 'error', 'data' repeated everywhere. This is because we couple data fetching to the component lifecycle, not navigation. But there's a much better way: move data fetching to the routing layer. Tools like TanStack Router do this brilliantly with loaders. The 'loader' function of a route is executed BEFORE its component is rendered. When the component assembles, the data is already there, ready to be used. The best? It natively integrates with the TanStack Query cache. If the data is already in the cache, navigation is instantaneous. No networking, no loading. The result is a ridiculously clean component. No useEffect, no useState for loading states, no try/catch. Just a hook that consumes the data. The gains are straightforward: ✅ Superior user experience, no layout shifts. ✅ Declarative component code, focused 100% on UI. ✅ Centralized, decoupled data logic. Putting fetches in 'useEffect' is a legacy anti-pattern. Data fetching is a concern of ROTA, not the component. Prioritize declarative clarity and decoupling. #React, #DesenvolvimentoWeb, #Frontend, #JavaScript, #TanStack, #ReactQuery, #BoasPraticas
To view or add a comment, sign in
-
-
Day 2 of Next.js deep dive 🚀 Just wrapped my head around the rendering paradigms, data fetching, and state management that make Next.js a beast for SaaS apps! 1. Rendering Paradigms - The Game Changer ✅ Server Components (default) = Data fetching + HTML on server = lightning-fast initial loads ✅ Client Components ("use client") = Interactivity + charts + forms where needed ✅ SSR/SSG/ISR all work together seamlessly in App Router Realization: Server Components aren't just "nice to have" - they're the foundation. Fetch data once on the server, ship minimal JS. This is why Next.js pages load like native apps. 2. Data Fetching - No More useEffect Hell tsx // Server Component (page.tsx) export default async function Dashboard() { const data = await fetch('api/analytics', { cache: 'force-cache' }) return <Stats data={data} /> } ✅ fetch() is built-in, cached by default, streaming, and Suspense-ready ✅ No more useEffect + useState + loading spinners everywhere ✅ Client components get props, not API calls 3. State Management - Simple & Smart ✅ URL state (/dashboard?tab=analytics&date=30d) = Shareable, bookmarkable ✅ Server Actions for mutations (action: async () => { ... }) ✅ Zustand/Jotai for complex client state (sidebar open, filters) ✅ No Redux needed for 90% of apps The mental model shift: React = Component tree Next.js = Route tree with server/client boundaries Building my SaaS dashboard tomorrow with: Server-rendered pages with fresh data Client-side charts + filters URL-driven tabs + date pickers Server Actions for CRUD Next.js isn't React with routing - it's React with a data layer, rendering strategy, and deployment pipeline built in. Who's building with App Router? What's your go-to state pattern? #NextJS #React #WebDev #SaaS #AppRouter
To view or add a comment, sign in
-
I’m excited to share my latest project: a high-performance Campaign Management System designed for modern advertising agencies. Building digital products for agencies requires a balance of speed, security, and intuitive UX. For this assessment, I focused on creating a scalable Full-Stack solution that handles live campaign metrics and AI-driven creative workflows. Key Technical Highlights: * Full-Stack Architecture: Built with React 18, Node.js, and PostgreSQL. * Data Visualization: Integrated interactive 30-day performance trends using Recharts. * AI-Assisted Workflows: Developed a multi-step Brief Builder with a simulated AI service for rapid creative direction. * Security & Integrity: Implemented JWT Authentication, API Rate Limiting, and Soft Deletes to protect sensitive agency data. * Performance: Optimized rendering using custom hooks (useDebounce) and React optimization patterns. I’m always looking for ways to bridge the gap between complex data and user-friendly interfaces. GitHub Repository: [https://lnkd.in/dJd8nFpH] Ameen Alam Junaid Ali Hafiz Ali Ahmed Faisal Ilyas Faisal ilyas Bilal Fareed Fahad Khan #FullStackDeveloper #ReactJS #NodeJS #WebDevelopment #AIIntegration #PostgreSQL #SoftwareEngineering #Portfolio
To view or add a comment, sign in
-
Ever find your web application dragging its feet, waiting for multiple pieces of data to load one after another? It's a common bottleneck, especially when dealing with several API endpoints. Sequential API calls can severely degrade user experience. Imagine fetching user details, then their order history, then product images – each request waiting for the previous one to complete. This "waterfall" effect can lead to frustratingly slow load times. The good news? JavaScript's `Promise.all()` is a game-changer for concurrently fetching data. Instead of waiting for each promise to resolve individually, `Promise.all()` lets you initiate multiple asynchronous operations in parallel and wait for *all* of them to complete. Here's a quick example of how to make your data fetching lightning fast: ```javascript async function fetchDashboardData() { try { const [userData, productsData, analyticsData] = await Promise.all([ fetch('/api/users/current').then(res => res.json()), fetch('/api/products').then(res => res.json()), fetch('/api/analytics/summary').then(res => res.json()) ]); console.log("User:", userData); console.log("Products:", productsData); console.log("Analytics:", analyticsData); // Now render your dashboard with all data available } catch (error) { console.error("Failed to fetch dashboard data:", error); } } fetchDashboardData(); ``` By leveraging `Promise.all()`, we're telling the browser to fire off all these requests at roughly the same time. The `await` then ensures our code proceeds only when *all* promises have successfully resolved. This significantly reduces the total time spent waiting, leading to a much snappier application and a happier user. Embracing asynchronous patterns like `Promise.all()` isn't just about syntax; it's about fundamentally improving the responsiveness and efficiency of your applications, leading to a better user experience and more robust architecture. What are your go-to strategies for optimizing API calls and improving front-end performance? Share your insights below! #JavaScript #WebDevelopment #PerformanceOptimization #CodingTips #SoftwareEngineering
To view or add a comment, sign in
-
🪟 Next.js Parallel Routes — render multiple pages in one layout. Most devs don't use this. Here's why you should 👇 Traditional routing swaps the whole page on navigation. Parallel Routes let multiple route segments live side by side — independently loading, independently erroring, independently streaming. How it works: Prefix folders with @ → they become slots. app/ ├── layout.js ├── @analytics/page.js └── @team/page.js Code Your layout receives them as props: export default function Layout({ children, analytics, team }) { return ( <div> {analytics} {team} </div> ); } Js Each slot streams independently — no slot blocks another. Real-world wins: → 📊 Analytics + team metrics on one dashboard — each fetches its own data → 🗂️ Inbox + message thread — split-view, URL-driven → 🔔 Modal overlays via Intercepting Routes (Parallel Routes' best friend) → 🔄 Per-slot loading.js & error.js — granular UX control The mindset shift: Stop thinking "one URL = one page". Start thinking "one layout = multiple independent route segments". This is what makes Next.js App Router genuinely different from pages/. Are you using Parallel Routes in production? Drop your use case 👇 https://lnkd.in/g7G4bmTs #Nextjs #React #AppRouter #Frontend #WebDev #AIEngineering
To view or add a comment, sign in
-
I’ve been diving into data fetching and caching in Next.js lately, and here’s a simple breakdown that helped me connect the dots 👇 🔹 Data Fetching Types SSR → Fetch data on every request (always fresh, but slower) SSG → Fetch at build time (super fast, but static) ISR → Static + auto अपडेट after a time (best balance) CSR → Fetch on client side (for interactive UI) 🔹 Modern App Router Approach Instead of special functions, Next.js now uses fetch() with built-in caching: cache: "force-cache" → works like SSG (fast, cached) cache: "no-store" → works like SSR (always fresh) next: { revalidate: 10 } → works like ISR (auto update) 🔹 Caching Layers (Important) Data Cache → stores API responses Full Route Cache → stores full HTML Router Cache → speeds up navigation Request Memoization → avoids duplicate fetch calls 🔹 Dynamic Routes Using generateStaticParams() we can pre-build dynamic pages at build time → better performance + SEO 🚀 🔹 Best Practice Always handle errors: if (!res.ok) throw new Error("Failed to fetch data"); 📌 Key takeaway: Next.js is all about balancing speed vs freshness. Choose the right strategy based on your use case. #NextJS #WebDevelopment #React #Frontend #JavaScript #FullStack #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