React受控input组件切换disabled状态后仍无法编辑问题求助
问题根因
输入框无法编辑是典型的React受控组件绑定逻辑错误导致的:
- 你的自定义Input组件先展开了
{...field}(从传入的rules参数判断,这是react-hook-form注册字段返回的对象,自带配套的value、onChange、onBlur等受控绑定属性),但后续又手动写了value={props.value},直接覆盖了field对象自带的受控值绑定逻辑,同时没有给input绑定对应的onChange事件来同步输入的内容。 - 你手动传给组件的
value绑定的是agent?.businessName,这个值只有接口返回、主动调用setAgent时才会更新,输入过程中没有任何逻辑同步修改这个状态,哪怕disabled状态切为可编辑,输入的内容也没法更新到绑定值上,表现出来就是输入框无法修改内容。
修复方案
两种方案选其一即可,不要混着用避免属性冲突。
方案1:适配现有react-hook-form逻辑(推荐)
不要手动给input传value属性,直接复用field对象的绑定逻辑,接口返回数据后用react-hook-form的reset方法填充默认值即可。
首先修改自定义Input组件,去掉手动写的value覆盖:
<input {...field} disabled={props.disabled} type={props.type} autoComplete={props.autoComplete} pattern={props.pattern} className={`mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm rounded-md ${ error ? 'border-red-500' : 'border-gray-500' } ${ props.disabled ? 'disabled:shadow-none disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200' : 'border-gray-500' } `} />
然后在页面逻辑中,接口返回数据后填充表单默认值,调用InputField时不需要手动绑定value:
// 从useForm中取出reset方法 const { reset } = useForm({ /* 保留你原有的表单配置 */ }) useEffect(() => { const fetchData = async () => { try { const { id } = params const agentUsers = await getEstaAgentUsers(parseInt(id!, 10)) const agentRes = await getEstateAgentById(parseInt(id!, 10)) setAgentUsers(agentUsers) setAgent(agentRes) // 将接口数据填充到表单值中 reset({ businessName: agentRes.businessName // 其余表单字段按同样方式填充 }) } catch (error) { toast.error(`${error}`) } } fetchData() }, []) // 组件调用 <PencilAltIcon className="block h-4 w-4" aria-hidden="true" onClick={handleInputField} /> <InputField name="businessName" label="Business name" disabled={!enableField} type="text" rules={{ required: 'This is required', }} />
方案2:自行实现受控组件逻辑
如果不使用react-hook-form管理表单状态,就去掉{...field}的展开,手动透传onChange事件,在输入时同步更新state。
首先修改自定义Input组件:
<input disabled={props.disabled} value={props.value ?? ''} onChange={props.onChange} type={props.type} autoComplete={props.autoComplete} pattern={props.pattern} className={`mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm rounded-md ${ error ? 'border-red-500' : 'border-gray-500' } ${ props.disabled ? 'disabled:shadow-none disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200' : 'border-gray-500' } `} />
调用组件时传入onChange事件,输入时同步更新agent状态:
<InputField name="businessName" label="Business name" disabled={!enableField} value={agent?.businessName ?? ''} onChange={(e) => { setAgent(prev => prev ? {...prev, businessName: e.target.value} : null) }} type="text" />
内容的提问来源于stack exchange,提问作者VickyR
相关产品推荐
相关产品推荐

