skip to Main Content

I am using the Next.js App Router architecture, and I have a post page that calls an API and passes the data to a component. I have already implemented simple interactions like clicking to change some styles, etc. However, how can I implement more complex features, such as clicking a button to fetch data again or adding/deleting/updating post? Since I am directly mapping the post data, I can’t change the state. I tried storing the post data in useState within useEffect and then mapping through the data in useState, but this loses the SSR effect, and the view-source ends up being empty.

How should I achieve this? Is it possible to sync server data into the initial component? Can the server data be stored globally? Or what should I search for to solve my problem?

// post page

"use client"
import PostItem from "./components/PostItem"
import { useState } from "react"

export default function PostPage() {
    const [activeId, setActiveId] = useState(0)

    // Assuming it’s data from the API
    const post = [
        {
            id: 101,
            title: "How to Learn JavaScript",
            content: "JavaScript is a versatile language...",
            author: "john_doe",
            created_at: "2024-10-01T10:20:30Z",
            tags: ["javascript", "programming", "tutorial"],
        },
        {
            id: 102,
            title: "Understanding CSS Grid",
            content: "CSS Grid is a powerful layout system...",
            author: "jane_smith",
            created_at: "2024-09-28T14:15:22Z",
            tags: ["css", "frontend", "web design"],
        },
        {
            id: 103,
            title: "Introduction to React",
            content: "React is a popular JavaScript library...",
            author: "mark_twain",
            created_at: "2024-08-22T08:45:12Z",
            tags: ["react", "javascript", "frontend"],
        },
    ]

    console.log({ post })

    return (
        <div className="flex flex-wrap gap-2 mt-4 justify-center items-center">
            {post.map((p) => {
                return (
                    <PostItem
                        key={p.id}
                        {...p}
                        onClick={() => setActiveId(p.id)}
                        isActive={activeId === p.id}
                    />
                )
            })}
        </div>
    )
}

// post item component
interface PostItemProps {
    id: number
    title: string
    content: string
    author: string
    created_at: string
    tags: Array<string>
    isActive?: boolean
    onClick: () => void
}

export default function PostItem(props: PostItemProps) {
    const { id, title, content, author, created_at, tags, isActive, onClick } =
        props

    return (
        <section
            className={`transition-all duration-500 cursor-pointer w-[200px] p-4 ${
                isActive
                    ? "bg-blue-700 text-yellow-200 rounded-lg"
                    : "bg-blue-600 text-white"
            } `}
            onClick={onClick}
        >
            <div className="text-xl font-bold mb-2">{title}</div>
            <div className="mb-2">{content}</div>
            <ul className="mb-2">
                {tags.map((t, index) => {
                    return <li key={index}>{t}</li>
                })}
            </ul>
        </section>
    )
}

I tried SSR data passing to components for interaction, but I’m not sure of the correct approach.

2

Answers


  1. you can use the revalidatePath('routeName)` in the server action of the data deletion, check the references in this link

    Login or Signup to reply.
  2. YOU CAN FOLLOW THIS APPROACH TO ACHIEVE SSR ALONG WITH OTHER CLIENT EVENTS:

    • You can make page server side and use server actions to make api call
      to fetch post and pass post data to your client component called in your server side page and in client component you can initially set postData in useState and them update it as you wish and use all js events in this client component. and if you have issue that you wont get updated data on your SSR page then you can use next revalidate in your server action.

    Example code structure:

    SSR PAGE:

    const fetchPosts=async()=>{
    const res = fetch('/posts',{ next: { revalidate: 0 } });
    const jsonRes = await  res?.json()
    
    return jsonRes;
    }
    
    const posts = await fetchPosts();
    

    now you can pass this posts in your client component and on change you can get new data on page. and on each CRUD operation on posts you can call revalidate(‘/posts’) to update posts on your SSR page

    I personally follow this approach to achieve SSR along with client side functionality if you find better approach let me know.
    Happy coding πŸ™‚

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search