Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I make Next.js 13 server-side components in the app directory that depend on useEffect for props?

I’m trying to write a Next.js 13 newsletter page in the app directory that uses server-side components that depend on useEffect for props. The useEffect fetches data from a REST API to get newsletters which will render the content of the page. The code I’m using is below. I’m having trouble figuring out how to configure the server-side components to work when I need to "use client" for interactivity. How can I make sure that the server-side components are rendered before it is sent to the client?

Code:

import Navbar from '@/components/navbar'
import Footer from '@/components/footer'
import Pagination from './pagination'
import IssueCards from './issueCards';
import { useState, useEffect } from 'react';
import axios from 'axios';


const Newsletters = () => {
    const [issues, setIssues] = useState([]);
    const [currentPage, setCurrentPage] = useState(1);
    const [issuesPerPage, setIssuesPerPage] = useState(5);

    useEffect(() => {
        const fetchIssue = async () => {
            const res = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API}/newsletters`)
            setIssues(res.data)
        }
        fetchIssue()
    }, [])
    
    // Change page
    const paginate = (pageNumber) => setCurrentPage(pageNumber);

    const indexOfLastIssue = currentPage * issuesPerPage;
    const indexOfFirstIssue = indexOfLastIssue - issuesPerPage;
    const currentIssues = issues.slice(indexOfFirstIssue, indexOfLastIssue)

    return (
        <>
            <Navbar />
            <div className="newsletter-container" id='newsletter-container'>
                <h1>Newsletters</h1>
                <hr></hr>
                <div className="newsletter-wrapper">
                    <IssueCards issues={currentIssues} />
                    <Pagination 
                        issuesPerPage={issuesPerPage} 
                        totalIssues={issues.length} 
                        paginate={paginate} 
                    />
                </div>
            </div>
            <Footer />
        </>
    );
}

export default Newsletters;

How do I configure Next.js 13 server-side components that depend on useEffect for props and ensure that the content is rendered before it is sent to the client?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I tried following the Nextjs docs on Server and Client components but I am unsure of how I can pass down the props information onto the server.

>Solution :

Unfortunately, server components don’t allow for hooks such as useEffect, see documentation here.

You have two main options:

  1. New way of fetching data
    Server components allow for a new way of fetching data in a component, described here.
    This approach would look something this:

    async function getData() {
      const res = await fetch('https://api.example.com/...');
      // The return value is *not* serialized
      // You can return Date, Map, Set, etc.
    
      // Recommendation: handle errors
      if (!res.ok) {
        // This will activate the closest `error.js` Error Boundary
        throw new Error('Failed to fetch data');
      }
    
      return res.json();
    }
    
    export default async function Page() {
     const data = await getData();
    
     return <main></main>;
    }
    
  2. Revert to client components
    Your other option is to use the use client directive at the top of your file and leaving Newsletter as a client component. Of course, this way, you wouldn’t get the benefits of server components, but this would prevent you from having to change your code substantially. Also, keep in mind that server components are still in beta.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading