React元素div类中如何定义key?表单字段值不更新求助
React表单添加新记录后字段值不更新的解决方法
你的问题和key无关,核心是受控组件的状态绑定错位:输入框的value绑定到了父组件传入的selectedTask,但onChange却更新本地状态dte/rmk,导致视图和状态不同步,添加新记录后看不到变化。
解决思路:统一状态来源
受控组件的value和onChange必须绑定同一个状态,二选一:
方案1:本地状态主导(适合新增/编辑复用的表单)
初始化时用selectedTask填充本地状态,后续所有输入操作都更新本地状态,提交时把本地状态传给父组件。
修改后的代码:
const AddTask = ({ onAdd, selectedTask, isReadOnly }) => { // 初始化本地状态,优先用selectedTask的值 const [dte, setdte] = useState(selectedTask?.dte || ""); const [rmk, setrmk] = useState(selectedTask?.rmk || ""); const [isChecked, setIsChecked] = useState(false); const onSubmit = (e) => { e.preventDefault(); // 阻止页面默认刷新行为 const data = { dte, rmk }; onAdd(data); // 提交后清空表单 setdte(""); setrmk(""); }; return ( <form className="add-form" onSubmit={onSubmit}> <div className="form-group row"> <label className="col-sm-2 col-form-label">日期 </label> <div className="col-sm-8"> <input className="form-control" type="Date" placeholder="添加日期" value={dte} // 绑定本地状态 onChange={(e) => setdte(e.target.value)} disabled={isReadOnly} /> </div> </div> <div className="form-group row"> <label className="col-sm-2 col-form-label">备注 </label> <div className="col-sm-8"> <input className="form-control" type="text" value={rmk} // 绑定本地状态 onChange={(e) => setrmk(e.target.value)} disabled={isReadOnly} /> </div> </div> {/* 新增提交按钮,否则无法触发提交 */} <button type="submit" className="mt-3" disabled={isReadOnly}>提交</button> </form> ); };
方案2:父组件状态主导(适合纯编辑场景)
如果表单是用来编辑selectedTask的,直接把输入框的value绑定到selectedTask,onChange时通知父组件更新selectedTask。
修改后的代码:
const AddTask = ({ onAdd, selectedTask, isReadOnly, onUpdateTask }) => { const [isChecked, setIsChecked] = useState(false); const onSubmit = (e) => { e.preventDefault(); onAdd(selectedTask); // 提交后可通知父组件清空selectedTask,恢复新增状态 }; return ( <form className="add-form" onSubmit={onSubmit}> <div className="form-group row"> <label className="col-sm-2 col-form-label">日期 </label> <div className="col-sm-8"> <input className="form-control" type="Date" placeholder="添加日期" value={selectedTask?.dte || ""} // 通知父组件更新selectedTask onChange={(e) => onUpdateTask({...selectedTask, dte: e.target.value})} disabled={isReadOnly} /> </div> </div> <div className="form-group row"> <label className="col-sm-2 col-form-label">备注 </label> <div className="col-sm-8"> <input className="form-control" type="text" value={selectedTask?.rmk || ""} // 通知父组件更新selectedTask onChange={(e) => onUpdateTask({...selectedTask, rmk: e.target.value})} disabled={isReadOnly} /> </div> </div> <button type="submit" className="mt-3" disabled={isReadOnly}>提交</button> </form> ); };
额外注意事项
- 原代码缺少
e.preventDefault(),会导致表单提交后页面刷新,丢失状态 - 没有提交按钮,用户无法触发提交操作
key属性只需要在循环渲染列表项时添加,单个表单字段不需要加key
内容的提问来源于stack exchange,提问作者Laila
相关产品推荐
相关产品推荐

