skip to Main Content

As a first-time user of NextJS 13, I am following their App directory structure. I have implemented a server-side rendered component that retrieves categories from my database using Prisma and displays them as a list on the page. Additionally, I have a client-side component that includes an "Add" button, which triggers a modal with a textbox and a "Submit" button to create a new category in the database.

Now, here’s where I’m encountering an issue. Since the client-side component relies on state management with UseState, it cannot directly access Prisma to create a new category on the server. Firstly, what is the preferred method for doing this? Should I define a new API route and POST data directly from the client component?

Secondly, and my main question, how can I dynamically display the newly posted data in the server-side component without requiring a full page refresh? In particular, is there a way to seamlessly add the new category to the existing list without reloading the entire page?

2

Answers


  1. At least as of now, it is not possible to update state of the Server Component similar to how you update state on the client side. For using prisma, you should define route handler. Recommended path would be /api/route.ts in the same directory that serves your page. Or, if you choose, you can also use pages/api for your REST API routes.

    Login or Signup to reply.
  2. Here’s a simplified example demonstrating the approach of creating a new category on the server and dynamically displaying the newly posted data in a server-side rendered component without a full page refresh using Next.js:

    1. Create an API route to handle category creation:

    Create a new file in your Next.js project’s pages/api directory, e.g., createCategory.js:


    
    import prisma from '../../lib/prisma';
    
    export default async function createCategory(req, res) {
      if (req.method === 'POST') {
        const { categoryName } = req.body;
    
        try {
          const newCategory = await prisma.category.create({
            data: {
              name: categoryName,
            },
          });
    
          res.status(201).json(newCategory);
        } catch (error) {
          res.status(500).json({ error: 'Error creating category' });
        }
      } else {
        res.status(405).json({ error: 'Method not allowed' });
      }
    }
    
    

    Client-side component for creating a new category:

    import React, { useState } from 'react';
    
    function CategoryForm() {
      const [categoryName, setCategoryName] = useState('');
    
      const handleSubmit = async (e) => {
        e.preventDefault();
    
        try {
          const response = await fetch('/api/createCategory', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({ categoryName }),
          });
    
          if (response.ok) {
            const newCategory = await response.json();
            // Update the category list or trigger a re-fetch
            // to include the newCategory in the UI
            // ...
          } else {
            console.error('Failed to create category');
          }
        } catch (error) {
          console.error('Error creating category:', error);
        }
      };
    
      return (
        <form onSubmit={handleSubmit}>
          <input
            type="text"
            value={categoryName}
            onChange={(e) => setCategoryName(e.target.value)}
            placeholder="Enter category name"
          />
          <button type="submit">Add</button>
        </form>
      );
    }
    

    Server-side rendered component for displaying the category list:

    import prisma from '../lib/prisma';
    
    export async function getServerSideProps() {
      const categories = await prisma.category.findMany();
      return {
        props: {
          categories,
        },
      };
    }
    
    function CategoryList({ categories }) {
      return (
        <ul>
          {categories.map((category) => (
            <li key={category.id}>{category.name}</li>
          ))}
        </ul>
      );
    }
    

    With this setup, when you submit the category form, the client-side component sends a POST request to the /api/createCategory API route. The server-side component (CategoryList) is initially rendered with the category data fetched from the server using getServerSideProps.

    Upon successful creation of the category on the server, the client-side component can update the category list by modifying the state or triggering a re-fetch of the category data. This can be done by updating the categories prop in the CategoryList component or refetching the data in a separate getServerSideProps function.

    This way, the newly posted category will be dynamically displayed in the server-side rendered CategoryList component without requiring a full page refresh.

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