我有一个联系表单,它是 Nextjs 15 项目中的客户端组件。
在遵循 Google captcha 的文档后,我已将 Google captcha v3 集成到我的项目中。
当有人提交联系表单时,会触发提交处理程序。该处理程序调用一个函数来生成验证码令牌和另一个函数,这是一个服务器操作,负责向网站所有者发送电子邮件。
在组件中,我使用 useActionState 挂钩能够通过 isPending 和 state 的值将服务器操作的状态转换为前端更好的用户体验。
我的组件:
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>
)
}
服务器动作:
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!']
}
}
我在handleSubmit 中遇到了formAction 的TypeScript 问题。我收到错误:“预期有 0 个参数,但得到了 2”。
如果我从 formAction 函数和 sendEmail 函数签名中删除 captchaToken 参数,问题就会消失。
如何将 captchaToken 与 formData 一起传递给 formAction 函数,以便可以通过 sendEmail 接收?
我们可以使用 bind 来达到此目的。
首先像这样更改你的 useActionState 钩子
const sendEmailWithCaptchaToken = sendEmail.bind(null, {
captchaToken: "123456abcdef",
})
const [state, formAction, isPending] = useActionState(sendEmailWithCaptchaToken, initialState)
然后像这样更改你的服务器操作
export async function sendEmail(
extras: { captchaToken: string },
prevState: { messages: string[] },
formData: FormData,
) {
console.log("extras", extras)
//...
}