如何用URL参数设置单选按钮默认值(Next.js + react-hook-form)
解决Next.js + React Hook Form单选按钮默认选中不生效问题
问题根源
Next.js客户端组件首次渲染时,router.query会是undefined或空对象——路由参数需要异步加载。你用defaultChecked设置初始选中状态,但这个属性仅在组件首次渲染时生效,后续路由参数更新后不会自动同步。另外,React Hook Form会接管表单状态,defaultChecked和受控表单状态容易产生冲突。
解决方案
- 监听
router.query的变化,用React Hook Form的setValue同步表单值 - 将单选按钮改为受控组件,由React Hook Form管理选中状态,移除
defaultChecked - 过滤无效的
accountType参数,仅在参数为buyer/seller时设置表单值
修改后的代码
Fields.jsx
import { forwardRef } from 'react' function Label({ id, children }) { return ( <label htmlFor={id}> {children} </label> ) } export const RadioFieldWithRef = forwardRef(function RadioField({ id, label, options, name, className = '', ...props }, ref) { return ( <div className={className}> {label && <Label id={id}>{label}</Label>} <div> {options.map((option) => { // 通过表单值判断当前选项是否被选中 const isChecked = props.value === option.value; return ( <div className="flex items-center" key={option.value}> <input id={option.value} name={name} type="radio" value={option.value} checked={isChecked} ref={ref} {...props} /> <label htmlFor={option.value}> {option.label} </label> </div> ) })} </div> </div> ) })
signup.jsx
import { useRouter } from 'next/router' import { useEffect } from 'react' import { RadioFieldWithRef } from '@/components/Fields' import { useForm } from "react-hook-form"; export default function Signup() { const router = useRouter() const { accountType } = router.query const { register, setValue, formState: { errors } } = useForm(); const accountTypeField = register("account_type", { required: "Must select account type" }) // 监听accountType变化,同步表单值 useEffect(() => { if (accountType && ['buyer', 'seller'].includes(accountType)) { setValue('account_type', accountType); } }, [accountType, setValue]) return ( <form> <RadioFieldWithRef label="I'm a ..." name="account_type" options={ [ { label: 'Buyer', value: 'buyer' }, { label: 'Seller', value: 'seller' }, ] } {...accountTypeField} /> {errors.account_type && <p className="text-red-500">{errors.account_type.message}</p>} <button type="submit">Submit</button> </form> ) }
关键说明
- 用
useEffect监听accountType的变化,确保路由参数加载完成后再设置表单值 - 将单选按钮改为受控组件,通过
props.value判断选中状态,完全由React Hook Form管理表单状态 - 增加无效参数过滤,避免非法值设置到表单中
- 保留表单校验逻辑,确保用户必须选择一个身份
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

