6

Im trying to understand React server components and how to render component state without the use of useState and useEffect. I have created a server component with an embedded client component and both fetch a small amount of data and display as JSON.

The client component works as expected and renders the json data fetched from the API.

main.client.tsx

import { useEffect, useState } from "react"

export default function Main() {
    let [data, setData] = useState(undefined);

    async function fetchData() {
        let value = await fetch("https://jsonplaceholder.typicode.com/posts");
        let result = await value.json();
        let slice = result.slice(0,2);
        return slice;
    }

    useEffect(()=>{
        fetchData().then(value => {
            setData(value);
            console.log("data", data)
        });
    }, [])

    return (<div className="component">
        <h1>Client Main</h1>
        {data &&
            <div>
                <pre>
                    {JSON.stringify(data, null, 2)}
                </pre>
            </div>
        }
    </div>)
}

The server component doesnt re-render the json data. Its basiically a duplicate of the client code without useEffect, useRef and useState because they are not availabe on the server.

It renders the initialised data but not the fetched data.

main.server.tsx

import Client from "../components/main.client"

export default function Main() {
    let data = {key: "initial value"};
    let hello = "hello world";
    
    async function fetchData() {
        let value = await fetch("https://jsonplaceholder.typicode.com/posts");
        let result = await value.json();
        let slice = result.slice(0,2);
        return slice;
    }

    fetchData().then(value => {
        data = [...value];
        console.log("data", data)
    });

    return (<div className="component">
        <h1>Server Main</h1>
        {hello}
        {data &&
            <div>
                <pre>
                    {JSON.stringify(data, null, 2)}
                </pre>
            </div>
        }
        <Client/>
    </div>)
}

how can i correctly assign the data array (returned from the fetch) so it renders on the server?

Laurence Fass
  • 1,614
  • 3
  • 21
  • 43
  • You can use async/await directly in your server components if you want to fetch on the server. State and effects generally aren't necessary unless you have a component running on the client that needs to do something interactive. – Nick McCurdy May 16 '23 at 07:05

1 Answers1

2

If you're using Next.JS, it's probably that you need to use "'use client';" before any import to fix this problem. See this example:

"use client";
import { useState } from "react";
import Image from "next/image";
import { Inter } from "@next/font/google";

Hope it helps you.