#Button Server Action with Payload

1 messages · Page 1 of 1 (latest)

stone gyro
#

I've the following code, I'd like to pass in the workspace Id to the deleteAction, and also disable it when deleting, and show an error on the UI when it fails, but not sure how to resolve the .bind thing.

export const WorkspaceButtons = ({ workspaceId }: { workspaceId: string }) => {
...
const [deleteState, deleteAction, isDeleting] = useActionState(
    deleteWorkspace.bind(null, workspaceId),
    {
      error: null,
    }
  );
...
return <>
...
      <form action={deleteWorkspace.bind(null, workspaceId)}>
        <Button
          disabled={isDeleting}
          type="submit"
          onClick={async () => {
            console.log("Delete workspace clicked");
          }}
          variant={"destructive"}
          className="w-full"
        >
          {t("WORKSPACE_DETAILS.DELETE")}
        </Button>
      </form>
</>;
steel plazaBOT
#

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

#

Based on the knowledge sources provided, I can offer some guidance on how to handle Server Actions with payloads in Next.js, though there are some limitations in the information available for your specific use case.

  1. Passing arguments to Server Actions:
    You're on the right track using the bind method to pass the workspaceId to your Server Action. This is a recommended approach according to the Next.js documentation (https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#passing-additional-arguments).

  2. Using useActionState:
    The useActionState hook you're using is not part of the standard Next.js API. It appears to be a custom hook or possibly from an older version of Next.js. The current recommended approach is to use useFormState for handling form state in Server Actions.

  3. Disabling the button and showing errors:
    To disable the button while deleting and show errors, you can use the useFormState hook from React. Here's how you might modify your code:

'use client'

import { useFormState } from 'react-dom'
import { deleteWorkspace } from '@/actions' // Assuming this is where your Server Action is defined

export const WorkspaceButtons = ({ workspaceId }: { workspaceId: string }) => {
  const deleteWorkspaceWithId = deleteWorkspace.bind(null, workspaceId)
  const [state, formAction] = useFormState(deleteWorkspaceWithId, { error: null })

  return (
    <form action={formAction}>
      <Button
        disabled={state.pending}
        type="submit"
        variant="destructive"
        className="w-full"
      >
        {state.pending ? 'Deleting...' : t("WORKSPACE_DETAILS.DELETE")}
      </Button>
      {state.error && <p>{state.error}</p>}
    </form>
  )
}
#

In this example:

  • We use useFormState to manage the form state, including pending status and errors.
  • The button is disabled when state.pending is true.
  • We display an error message if state.error exists.

Note that you'll need to modify your deleteWorkspace Server Action to return the appropriate state object, including error and pending properties.

  1. Handling the onClick event:
    Since you're using a Server Action, you typically don't need to handle the onClick event separately. The form submission will trigger the Server Action. If you need to perform additional client-side actions, you can use the onSubmit event of the form instead.

Remember to adjust your Server Action to handle errors appropriately and return the correct state object. For example:

'use server'

export async function deleteWorkspace(workspaceId: string, prevState: any) {
  try {
    // Perform deletion logic here
    return { error: null, pending: false }
  } catch (error) {
    return { error: 'Failed to delete workspace', pending: false }
  }
}

This approach should allow you to pass the workspaceId to your Server Action, disable the button during deletion, and show errors on the UI when the action fails.

Next.js Server Actions and Mutations (https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#passing-additional-arguments)

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@stone gyro Kapa.ai is still learning and improving, please let me know how I did by reacting below.

stone gyro
#

@steel plaza what if I want to send a toast notification of the error?

steel plazaBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

To send a toast notification for errors when using Server Actions in Next.js, you can combine the server-side error handling with client-side toast notifications. Here's how you can modify your approach to include toast notifications:

  1. First, you'll need to use a toast library of your choice. A popular option is react-hot-toast, but you can use any library that suits your needs.

  2. In your Server Action, return the error message as before:

'use server'

export async function deleteWorkspace(workspaceId: string, prevState: any) {
  try {
    // Perform deletion logic here
    return { message: 'Workspace deleted successfully', error: null }
  } catch (error) {
    return { message: null, error: 'Failed to delete workspace' }
  }
}
  1. In your client component, use the useFormState hook to handle the form state and show the toast notification based on the returned state:
'use client'

import { useFormState } from 'react-dom'
import { toast } from 'react-hot-toast' // Import your chosen toast library
import { deleteWorkspace } from '@/actions'

export const WorkspaceButtons = ({ workspaceId }: { workspaceId: string }) => {
  const deleteWorkspaceWithId = deleteWorkspace.bind(null, workspaceId)
  const [state, formAction] = useFormState(deleteWorkspaceWithId, { message: null, error: null })

  // Show toast notification when state changes
  React.useEffect(() => {
    if (state.error) {
      toast.error(state.error)
    } else if (state.message) {
      toast.success(state.message)
    }
  }, [state])

  return (
    <form action={formAction}>
      <Button
        disabled={state.pending}
        type="submit"
        variant="destructive"
        className="w-full"
      >
        {state.pending ? 'Deleting...' : t("WORKSPACE_DETAILS.DELETE")}
      </Button>
    </form>
  )
}

In this example:

#
  • We use useFormState to manage the form state, including the error message or success message returned from the Server Action.
  • We use a useEffect hook to show a toast notification whenever the state changes. If there's an error, it shows an error toast; if there's a success message, it shows a success toast.
  • The button is disabled when state.pending is true, preventing multiple submissions.

This approach allows you to handle errors server-side and display them client-side using toast notifications. It provides a good user experience by giving immediate feedback about the result of the action.

Remember to wrap your app with the toast provider if your chosen library requires it.

Next.js Server Actions and Mutations (https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#server-side-validation-and-error-handling)

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: