React中如何保存输入框字段修改?解决切换后数据丢失问题
解决React输入框切换后修改内容丢失的问题
问题根源
当前输入框使用defaultValue(非受控模式),且未将用户修改同步到组件状态中,切换div时会重新从原始activeFields读取数据,导致之前的修改丢失。需要改为受控组件,并维护一个临时状态保存用户未提交的修改。
1. 修改TextInput组件,支持受控模式与回调
扩展绑定接口添加输入变化回调,将输入框改为受控组件,绑定value和onChange事件:
import "./text-field.scss"; import { Form } from "react-bootstrap"; import { Component } from "../../utils/stateless-component"; // 扩展Bindings接口,新增输入变化回调 export interface ITextInputBindings { onChange?: (value: string, fieldId: string | undefined) => void; } export interface ITextInputConfig { type: "text" | "dateTime" | "enumeration" | "guid" | undefined, id: string | undefined, label: string | undefined, placeholder?: string, required: boolean, autofocus?: boolean, value?: string } class TextInput extends Component<ITextInputConfig,ITextInputBindings> { handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const { value } = e.target; // 将新值和字段ID传递给父组件 this.bindings.onChange?.(value, this.config.id); } render() { return ( <div className="textInput"> <Form.Group className="mb-3 textInput-group"> <Form.Label htmlFor={this.config.id}>{this.config.label}</Form.Label> <Form.Control type={this.config.type} placeholder={this.config.placeholder} required={this.config.required} id={this.config.id} autoFocus={this.config.autofocus} value={this.config.value || ""} // 受控组件绑定value onChange={this.handleInputChange} // 绑定输入变化事件 /> </Form.Group> </div> ); } } export default TextInput;
2. 父组件维护临时修改状态,同步输入变化
在父组件state中添加临时对象保存未提交的修改,渲染时优先使用临时状态的值,并传递回调更新状态:
// 父组件类中初始化state constructor(props) { super(props); this.state = { activeFields: {}, tempEditedFields: {} // 存储用户未提交的字段修改 }; } // 处理字段值变化的方法 handleFieldUpdate = (newValue, fieldKey) => { this.setState(prevState => ({ tempEditedFields: { ...prevState.tempEditedFields, [fieldKey]: newValue // 按字段ID存储修改后的值 } })); } // 渲染部分修改 <div className="detailsPage-panel-right"> { this.state.activeFields?.fields?.map(field => { const config = this.config.fields.find(fieldConfig => fieldConfig.key === field.key) // 优先使用临时修改的值,无修改则用原始值 const currentValue = this.state.tempEditedFields[field.key] || field.value; const inputConfig = { type: config?.dataType.type, id: config?.key, label: config?.displayName, required: false, autofocus: false, value: currentValue }; const inputBindings: ITextInputBindings = { onChange: this.handleFieldUpdate // 传递回调给子组件 } return ( <div key={`${this.state.activeFields.key}-${field.key}`}> <TextInput config={inputConfig} bindings={inputBindings}></TextInput> </div> ) }) } </div>
3. 保存时的处理(可选)
点击保存按钮时,将临时修改合并到原始数据中,完成提交后清空临时状态:
handleSave = () => { const { activeFields, tempEditedFields } = this.state; // 合并修改后的字段数据 const updatedFields = activeFields.fields.map(field => ({ ...field, value: tempEditedFields[field.key] || field.value })); // 调用API提交修改(示例) // api.saveFields({ ...activeFields, fields: updatedFields }) // .then(() => { // this.setState({ tempEditedFields: {} }); // }); }
内容的提问来源于stack exchange,提问作者edche
相关产品推荐
相关产品推荐

