Next.js:如何通过表单组件向Server Action传递fetchuserid参数
解决useFormState中传递额外参数给Server Action的问题
核心思路是通过闭包包装Server Action函数,把组件接收到的fetchuserid注入进去——因为useFormState要求绑定的action函数只能接收formState和formData两个参数,直接传递带三个参数的userAddBalance会不匹配。
修改步骤:
- 在
addbalanceform.tsx中,把useFormState里的userAddBalance替换成一个闭包函数,在内部调用userAddBalance时带上fetchuserid参数:
// 原代码 const [formState, action] = useFormState( userAddBalance, EMPTY_FORM_STATE ); // 修改后 const [formState, action] = useFormState( (currentState, formData) => userAddBalance(currentState, formData, fetchuserid), EMPTY_FORM_STATE );
- (可选但强烈推荐)修复Server Action中的SQL注入风险:
原代码直接拼接amountInCents到SQL语句中,存在安全隐患,改成参数化查询:
// 原代码 const writeuser = db.prepare( `UPDATE user_registry SET kaffeestand = ${amountInCents} WHERE id = ?1` ); writeuser.run( { 1: fetchuserid}); // 修改后 const writeuser = db.prepare( `UPDATE user_registry SET kaffeestand = ?2 WHERE id = ?1` ); writeuser.run({ 1: fetchuserid, 2: amountInCents });
修改后的完整addbalanceform.tsx:
'use client'; import { useFormState } from "react-dom"; import { userAddBalance } from "./adddata"; import SubmitButton from "./submit-button"; import { EMPTY_FORM_STATE } from "./utils"; import { FieldError } from "./utils"; import { useToastMessage } from "./use-toast-message"; import { useFormReset } from "./useformreset"; export default function AddBalanceForm ({ fetchuserid }: { fetchuserid: number }) { const [formState, action] = useFormState( (currentState, formData) => userAddBalance(currentState, formData, fetchuserid), EMPTY_FORM_STATE ); const noScriptFallback = useToastMessage(formState); const formRef = useFormReset(formState); return ( <form action={action} className="flex flex-col gap-y-2" ref={formRef}> <label htmlFor="amount">amount</label> <textarea id="amount" name="amount" className="border-2" /> <span className="text-xs text-red-400"> <FieldError formState={formState} name="text" /> </span> <SubmitButton label="Create" loading="Creating ..." /> <span className="font-bold">{formState.message}</span> {noScriptFallback} </form> ); };
这样就能成功把fetchuserid传递给Server Action,用于数据库更新操作了。
内容的提问来源于stack exchange,提问作者idontknowwhatimdoing
相关产品推荐
相关产品推荐

