{A}

Fetch data in Next.js 15 (App Router)

axelj123
axelj123

Publicado el 28 de diciembre de 2024

Server Components

Server Components allow you to run fetch logic directly on the server. This is the recommended approach for most use cases.

jsx
// src/app/posts/page.jsx
import React from 'react';

async function fetchPosts() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts');
const posts = await res.json();
return posts;
}

export default async function Posts() {
const posts = await fetchPosts();

return (
<div>
<h1>List of Posts</h1>
{posts.map((post) => (
<div key={post.id}>
<h2>{post.title}</h2>
<p>{post.body}</p>
</div>
))}
</div>
);
}

Advantages of Server

  • Better initial performance
  • Data is fetched on the server
  • No additional states required
  • SEO optimized

Client Components

For cases where you need to fetch data in response to user actions or need dynamic updates, you can use Client Components with React hooks.

jsx
'use client';

import React, { useEffect, useState } from 'react';

const Posts = () => {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);

 useEffect(() => {
 const fetchPosts = async () => {
 setLoading(true);
 const res = await fetch('https://jsonplaceholder.typicode.com/posts');
 const data = await res.json();
 setPosts(data);
 setLoading(false);
 };

 fetchPosts();
 }, []);

 if (loading) return <p>Loading...</p>;

 return (
 <div>
 <h1>List of Posts</h1>
 {posts.map((post) => (
 <div key={post.id}>
 <h2>{post.title}</h2>
 <p>{post.body}</p>
 </div>
 ))}
 </div>
 );
};

export default Posts;

Advantages of Client

  • Immediate interactivity
  • Dynamic data updates
  • Ideal for features like real-time search

Error Handling

It is crucial to implement proper error handling when working with APIs:

jsx
'use client';

import React, { useEffect, useState } from 'react';

const Posts = () => {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
 const fetchPosts = async () => {
 setLoading(true);
 try {
 const res = await fetch('https://jsonplaceholder.typicode.com/posts');
 if (!res.ok) {
 throw new Error('Could not get data');
 }
 const data = await res.json();
 setPosts(data);
 } catch (error) {
 setError(error.message);
 } finally {
 setLoading(false);
 }
 };

 fetchPosts();
 }, []);

 if (loading) return <p>Loading...</p>;
 if (error) return <p>Error: {error}</p>;

 return (
 // ...render component
 );
};

Key Considerations

  1. Server vs Client Components:
  • Use Server Components for static or SEO-friendly data
  • Use Client Components for interactivity and dynamic updates
  1. State Handling:
  • Implement loading and error states
  • Provide visual feedback to the user
  1. Optimization:
  • Use Next.js' built-in caching
  • Implement robust error handling

Additional Resources