Next.js Client-Side Data Fetching — useEffect, SWR & React Query
Client-side fetching ee cases లో useful:
- Data user interaction meedha depend అయినప్పుడు (search-as-you-type, filters)
- Frequently-changing data, real-time polling అవసరమైనప్పుడు
- Component mount అయిన తర్వాత matrame fetch చేయాల్సినప్పుడు (browser-only data meedha depend అయితే)
"use client";
import { useState, useEffect } from "react";
export default function LiveStats() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch("https://api.example.com/live-stats")
.then((res) => res.json())
.then((json) => setData(json))
.catch((err) => setError(err.message))
.finally(() => setLoading(false));
}, []);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return <p>Active Users: {data.activeUsers}</p>;
}
3 states manage చేయాల్సి ఉంటుంది — loading, error, data. useEffect(() => {"{"}...{"}"}, []) component mount అయిన తర్వాత ఒక్కసారి matrame run అవుతుంది.
Manual loading/error state boilerplate తగ్గించడానికి, SWR (Vercel's own data-fetching library) వాడొచ్చు — caching, revalidation, error retry automatic గా handle చేస్తుంది:
"use client";
import useSWR from "swr";
const fetcher = (url: string) => fetch(url).then((res) => res.json());
export default function LiveStats() {
const { data, error, isLoading } = useSWR("https://api.example.com/live-stats", fetcher);
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Failed to load</p>;
return <p>Active Users: {data.activeUsers}</p>;
}
SWR automatic ga background revalidation, focus-triggered refetching, and caching handle చేస్తుంది — code chాలా tగ్గుతుంది.
Blog post content, product descriptions లాంటి static data ని useEffect తో client meedha fetch చేయడం — ఇది SEO ni damage చేస్తుంది (search engines empty HTML చూస్తాయి) and page load slow చేస్తుంది. Static content ఎప్పుడూ Server Component లోనే fetch చేయాలి.
Write a client component that fetches the current time from an API every time a button is clicked, showing a loading state while fetching.
"use client";
import { useState } from "react";
export default function TimeChecker() {
const [time, setTime] = useState("");
const [loading, setLoading] = useState(false);
async function checkTime() {
setLoading(true);
const res = await fetch("https://api.example.com/time");
const data = await res.json();
setTime(data.currentTime);
setLoading(false);
}
return (
<div>
<button onClick={checkTime}>Check Time</button>
{loading ? <p>Loading...</p> : <p>{time}</p>}
</div>
);
}
Q SWR, React Query madhya ఏది వాడాలి?
రెండూ similar goals ఉన్నవి — caching, revalidation, error retry. SWR చిన్నది, Vercel maintain చేస్తుంది (Next.js తో బాగా fit అవుతుంది). React Query ఎక్కువ features (mutations, devtools) కలిగి ఉంటుంది, larger apps కి popular.
Q Server Component data ni Client Component కి initial data గా pass చేయవచ్చా?
Avunు, ఇది common pattern — Server Component లో initial data fetch చేసి, prop గా Client Component కి pass చేసి, తర్వాత client-side hook (SWR) fallbackData గా వాడొచ్చు — fast initial load + live updates రెండూ వస్తాయి.
Q useEffect dependency array ([]) ఖాళీగా ఎందుకు ఉంచాలి?
Empty array [], effect ni component mount అయిన ఒక్కసారి matrame run చేయమని చెప్తుంది. Dependency ఏదైనా pెడితే (like [userId]), అది change అయినప్పుడల్లా effect మళ్ళీ run అవుతుంది.