#button

1 messages · Page 1 of 1 (latest)

reef quartz
#

If I have a button component that gets props a book is liked or not then change the text and also when clicking the button does a mutation in the db. how can i make it as a server component

west wolfBOT
#

Hi @reef quartz. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To create a button component that changes its text based on whether a book is liked or not and performs a mutation in the database when clicked, you can use a Server Action in a Server Component. Below is an example of how you can achieve this in Next.js:

  1. Define the Server Action: Create a new file for your server actions and use the "use server" directive to mark the functions as Server Actions.
// app/actions.ts
'use server'

export async function toggleLike(bookId: string, isLiked: boolean) {
  // Perform the mutation in the database
  // Example: await db.books.update({ id: bookId, liked: !isLiked })
  return !isLiked; // Return the new liked state
}
  1. Create the Server Component: Use the Server Action in your Server Component and pass it down to the Client Component as a prop.
// app/book-button.tsx
import { toggleLike } from './actions'

type Props = {
  bookId: string;
  initialLiked: boolean;
}

export default function BookButton({ bookId, initialLiked }: Props) {
  async function handleToggleLike() {
    'use server'
    const newLikedState = await toggleLike(bookId, initialLiked);
    return newLikedState;
  }

  return <ClientBookButton bookId={bookId} initialLiked={initialLiked} handleToggleLike={handleToggleLike} />
}
  1. Create the Client Component: This component will handle the UI updates and call the Server Action passed as a prop.
// app/client-book-button.tsx
'use client'

import { useState } from 'react'

type Props = {
  bookId: string;
  initialLiked: boolean;
  handleToggleLike: () => Promise<boolean>;
}

export default function ClientBookButton({ bookId, initialLiked, handleToggleLike }: Props) {
  const [isLiked, setIsLiked] = useState(initialLiked);
#

return (
<button
onClick={async () => {
const newLikedState = await handleToggleLike();
setIsLiked(newLikedState);
}}
>
{isLiked ? 'Unlike' : 'Like'}
</button>
)
}


In this setup:
- The `toggleLike` function is defined as a Server Action in `app/actions.ts`.
- The `BookButton` component is a Server Component that uses the `toggleLike` Server Action and passes it to the `ClientBookButton` component.
- The `ClientBookButton` component handles the UI and calls the Server Action when the button is clicked.

This approach ensures that the mutation is performed on the server, while the UI updates are handled on the client side.

For more information on Server Actions and how to use them in Next.js, you can refer to the **Next.js documentation on Server Actions and Mutations** (<https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#convention>).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------