React Hook更新表单state时覆盖原值无法追加多键值对问题
React表单Hook更新state时覆盖旧值问题修复
问题根因
三个直接导致state仅保留最后输入字段的问题:
- 闭包陷阱:自定义Hook中更新state时直接展开
...value,这个value是回调创建时捕获的初始空对象,每次更新都是基于空对象合并新字段,自然会丢失之前输入的内容。React中更新state如果依赖上一次的state值,必须使用函数式更新写法,才能拿到最新的state快照。 - useCallback依赖缺失:子组件中
useCallback传入空依赖数组,导致handleChange永远持有首次渲染时的onFormChange、onTypeChange、formType旧引用,关联的都是陈旧state值,进一步放大闭包问题。 - 表单值绑定错误:输入框的value属性写为
values.formType,相当于固定读取values下key为formType的属性,而非读取key等于当前formType变量值的内容,会导致输入框无法正确回显已填内容。
修复代码
1. 修正自定义Hook,使用函数式更新
// hook.jsx import { useState } from 'react'; const useSetForm = () => { const [value, setValue] = useState({}); const setForm = (event) => { event?.preventDefault?.(); // 函数式更新,prev为当前最新的state,不存在闭包陈旧问题 setValue((prev) => ({ ...prev, [event.target.name]: event.target.value })) } return [value, setForm] } export default useSetForm
2. 修正子组件,补全依赖、修复值绑定
// child.jsx import { useCallback } from 'react'; const Forms = ({ formType, onFormChange, values, onTypeChange, error }) => { const handleChange = useCallback((event) => { onTypeChange(formType) onFormChange(event) // 补全所有回调内用到的外部值作为依赖,保证拿到最新引用 }, [onFormChange, onTypeChange, formType]) return ( <input className='createform-input' placeholder={formType} name={formType} // 动态取对应formType的值,兜底空字符串避免输入框非受控告警 value={values[formType] || ''} onChange={handleChange} /> ) } export default Forms
父组件注意事项
父组件中用到的setTypes方法如果也是更新state的逻辑,同样建议使用函数式更新写法,避免同类闭包问题。
改完之后依次填写所有输入框,就能得到包含所有字段的完整state对象,不会再出现字段被覆盖的问题。
内容的提问来源于stack exchange,提问作者bitchwhocodes
相关产品推荐
相关产品推荐

