typescript - How to Pass Additional Arguments to formAction in Next.js 15 Using useActionState? - Stack Overflow

admin2025-04-27  2

I have a contact form that's a client component in a Nextjs 15 project.

I've integrated Google captcha v3 into my project after following the Google captcha's documentation.

When someone submits the contact form, a submission handler is triggered. This handler calls a function to generate a Captcha token and another function, which is a server action, responsible for sending an email to the website owner.

In the component, I'm using the useActionState hook to be able to translate the server action's state to a better user experience on the frontend through the values of isPending and state.

My component:

    const initialState = {
    status: 'success',
    messages: [],
    } 
    const Contact = () => {
      const [state, formAction, isPending] = useActionState(sendEmail, initialState)

      const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
      event.preventDefault()
    
      const captchaToken = await getCaptchaToken()
    
      const formData = new FormData(event.currentTarget)
      formAction(formData, captchaToken)
    }

    return (
      <div>
        <h2>
          Contact
        </h2>
        <form onSubmit={handleSubmit}>
         <label>
          Name
          <input
            required
            type='text'
            name='fname'
            placeholder='enter your first name'
          />
         </label>

         <label>
          Email
          <input
            required
            type='email'
            name='email'
            placeholder='enter your email'/>
         </label>

         <button>
          {isPending ? 'Pending' : 'Submit'}
         </button>
         {state.messages.length > 0 &&
          state.messages.map((message, index) => {
            return (
              <p
                key={index}
              >
                {message}
              </p>
            )
          })}
      </form>
    </div>
  )
}

    

The server action:

        export async function sendEmail(
          prevState: { messages: string[] },
          formData: FormData,
          captchaToken: string
        ) {
         // Do some logic with the token and the formData
         return {
          status: 'success',
          messages: ['Thank you for contacting us!']
         }
      }

I’m facing a TypeScript issue with formAction that's in the handleSubmit. I’m getting the error: "Expected 0 arguments, but got 2".

If I remove the captchaToken argument from the formAction function and the sendEmail function signature, the issue disappears.

How can I pass the captchaToken to the formAction function along with the formData so it can be received by sendEmail?

I have a contact form that's a client component in a Nextjs 15 project.

I've integrated Google captcha v3 into my project after following the Google captcha's documentation.

When someone submits the contact form, a submission handler is triggered. This handler calls a function to generate a Captcha token and another function, which is a server action, responsible for sending an email to the website owner.

In the component, I'm using the useActionState hook to be able to translate the server action's state to a better user experience on the frontend through the values of isPending and state.

My component:

    const initialState = {
    status: 'success',
    messages: [],
    } 
    const Contact = () => {
      const [state, formAction, isPending] = useActionState(sendEmail, initialState)

      const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
      event.preventDefault()
    
      const captchaToken = await getCaptchaToken()
    
      const formData = new FormData(event.currentTarget)
      formAction(formData, captchaToken)
    }

    return (
      <div>
        <h2>
          Contact
        </h2>
        <form onSubmit={handleSubmit}>
         <label>
          Name
          <input
            required
            type='text'
            name='fname'
            placeholder='enter your first name'
          />
         </label>

         <label>
          Email
          <input
            required
            type='email'
            name='email'
            placeholder='enter your email'/>
         </label>

         <button>
          {isPending ? 'Pending' : 'Submit'}
         </button>
         {state.messages.length > 0 &&
          state.messages.map((message, index) => {
            return (
              <p
                key={index}
              >
                {message}
              </p>
            )
          })}
      </form>
    </div>
  )
}

    

The server action:

        export async function sendEmail(
          prevState: { messages: string[] },
          formData: FormData,
          captchaToken: string
        ) {
         // Do some logic with the token and the formData
         return {
          status: 'success',
          messages: ['Thank you for contacting us!']
         }
      }

I’m facing a TypeScript issue with formAction that's in the handleSubmit. I’m getting the error: "Expected 0 arguments, but got 2".

If I remove the captchaToken argument from the formAction function and the sendEmail function signature, the issue disappears.

How can I pass the captchaToken to the formAction function along with the formData so it can be received by sendEmail?

Share Improve this question edited Jan 11 at 19:14 Drew Reese 205k18 gold badges246 silver badges274 bronze badges asked Jan 11 at 13:34 karimkarim 134 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

We can use bind for this purpose.

First change your useActionState hook like that

const sendEmailWithCaptchaToken = sendEmail.bind(null, {
    captchaToken: "123456abcdef",
})

const [state, formAction, isPending] = useActionState(sendEmailWithCaptchaToken, initialState)

then change your server action like that

export async function sendEmail(
    extras: { captchaToken: string },
    prevState: { messages: string[] },
    formData: FormData,
) {
    console.log("extras", extras)
    //...
}
转载请注明原文地址:http://anycun.com/QandA/1745709488a91136.html