You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 01:31:00