React表单提交:如何传递多行修改后的数据?
仅提交修改过的FeatureID与DisplayOrder数据的实现方案
问题背景
我通过API获取数据,在表格行中展示Feature ID和可编辑的DisplayOrder输入框。用户可修改多行的DisplayOrder值,但当前表单提交仅能传递一组FeatureID和DisplayOrder,希望在提交时仅传递所有修改过的FeatureID与DisplayOrder数据(例如仅FeatureID 11和13的排序修改后,只提交这两组信息),请问如何通过Post API实现该更新操作?
数据示例
[ {"FeatureID":"11","DescriptionText":"Travel","FeatureText":"Feature2","DisplayOrder":"1","Date":"08/30/2011","FeatureName":"Research"}, {"FeatureID":"12","DescriptionText":"Sport","FeatureText":"Feature3","DisplayOrder":"2","Date":"08/30/2011","FeatureName":"Research"}, {"FeatureID":"13","DescriptionText":"Art","FeatureText":"Feature4","DisplayOrder":"3","Date":"08/30/2011","FeatureName":"Research"} ]
现有代码
import React from "react"; export class EditFeatures extends React.Component { constructor(props) { super(props); this.state = { FeatureID: "", DisplayOrder: "", DescriptionText: "", FeatureText: "", Feature: [], }; this.handleSubmit = this.handleSubmit.bind(this); } componentDidMount() { this.DisplayFeatures(); } DisplayFeatures() { fetch(REQUEST_URL, { "Content-Type": "application/xml; charset=utf-8" }) .then((response) => response.json()) .then((data) => { this.setState({ Feature: data, loading: false, }); }); } handleSubmit(event) { event.preventDefault(); const FeatureID = this.state.FeatureID; const DisplayOrder = this.state.DisplayOrder; const data = { FeatureID, DisplayOrder, }; fetch(REQUEST_URL, { method: "POST", body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, }) .then((response) => response.json()) .catch((error) => console.error("Error:", error)) .then((response) => console.log("Success", data)); window.location.href = "/"; } render() { return ( <div> <form onSubmit={this.handleSubmit}> <table> <tbody> {this.state.Feature.map((item, index) => { return [ <tr key={item.FeatureID}> <td> <input type="text" id={item.FeatureID} name="DisplayOrder" value={item.DisplayOrder} onChange={(ev) => { const newFeature = this.state.Feature.map((f) => { if (f.FeatureID == ev.target.id) { f.DisplayOrder = ev.target.value; } return f; }); this.setState({ Feature: newFeature }); }} /> </td> <td>{item.DescriptionText}</td> <td>{item.FeatureTex}</td> </tr>, ]; })} </tbody> </table> <button type="submit" name="submit"> Update </button> </form> </div> ); } } export default EditFeatures;
实现方案
核心思路是备份原始数据,提交时对比当前值与原始值,筛选出修改过的条目再发送请求,具体步骤如下:
步骤1:保存原始数据到状态
在获取数据时,同步保存一份原始数据副本,作为后续对比修改的基准:
componentDidMount() { this.DisplayFeatures(); } DisplayFeatures() { fetch(REQUEST_URL, { "Content-Type": "application/xml; charset=utf-8" }) .then((response) => response.json()) .then((data) => { this.setState({ Feature: data, originalFeature: [...data], // 备份原始数据 loading: false, }); }) .catch(error => { console.error("获取数据失败:", error); this.setState({ loading: false }); }); }
步骤2:修改提交逻辑,筛选修改条目
在handleSubmit中,遍历当前数据与原始数据对比,只保留DisplayOrder发生变化的条目,再整理成提交格式:
handleSubmit(event) { event.preventDefault(); // 筛选出修改过的Feature const updatedFeatures = this.state.Feature.filter(current => { const originalItem = this.state.originalFeature.find(f => f.FeatureID === current.FeatureID); return originalItem && originalItem.DisplayOrder !== current.DisplayOrder; }); // 整理成仅包含FeatureID和DisplayOrder的提交数据 const submitData = updatedFeatures.map(item => ({ FeatureID: item.FeatureID, DisplayOrder: item.DisplayOrder })); // 无修改时直接跳转,避免无效请求 if (submitData.length === 0) { console.log("没有修改的数据需要提交"); window.location.href = "/"; return; } // 发送POST请求,传递修改后的数组 fetch(REQUEST_URL, { method: "POST", body: JSON.stringify(submitData), headers: { "Content-Type": "application/json" }, }) .then((response) => response.json()) .catch((error) => console.error("提交失败:", error)) .then(() => { console.log("修改成功"); window.location.href = "/"; }); }
步骤3:修正状态初始化与渲染细节
- 初始化状态时添加
originalFeature和加载状态:
constructor(props) { super(props); this.state = { Feature: [], originalFeature: [], loading: true, }; this.handleSubmit = this.handleSubmit.bind(this); }
- 修正渲染时的拼写错误(
FeatureTex改为FeatureText),并优化状态更新的不可变性:
<input type="text" id={item.FeatureID} name="DisplayOrder" value={item.DisplayOrder} onChange={(ev) => { const newFeature = this.state.Feature.map((f) => { if (f.FeatureID === ev.target.id) { return { ...f, DisplayOrder: ev.target.value }; // 用展开运算符创建新对象,避免直接修改原状态 } return f; }); this.setState({ Feature: newFeature }); }} />
完整修改后的代码
import React from "react"; export class EditFeatures extends React.Component { constructor(props) { super(props); this.state = { Feature: [], originalFeature: [], loading: true, }; this.handleSubmit = this.handleSubmit.bind(this); } componentDidMount() { this.DisplayFeatures(); } DisplayFeatures() { fetch(REQUEST_URL, { "Content-Type": "application/xml; charset=utf-8" }) .then((response) => response.json()) .then((data) => { this.setState({ Feature: data, originalFeature: [...data], loading: false, }); }) .catch(error => { console.error("获取数据失败:", error); this.setState({ loading: false }); }); } handleSubmit(event) { event.preventDefault(); const updatedFeatures = this.state.Feature.filter(current => { const originalItem = this.state.originalFeature.find(f => f.FeatureID === current.FeatureID); return originalItem && originalItem.DisplayOrder !== current.DisplayOrder; }); const submitData = updatedFeatures.map(item => ({ FeatureID: item.FeatureID, DisplayOrder: item.DisplayOrder })); if (submitData.length === 0) { console.log("没有修改的数据需要提交"); window.location.href = "/"; return; } fetch(REQUEST_URL, { method: "POST", body: JSON.stringify(submitData), headers: { "Content-Type": "application/json" }, }) .then((response) => response.json()) .catch((error) => console.error("提交失败:", error)) .then(() => { console.log("修改成功"); window.location.href = "/"; }); } render() { if (this.state.loading) { return <div>加载中...</div>; } return ( <div> <form onSubmit={this.handleSubmit}> <table> <tbody> {this.state.Feature.map((item) => ( <tr key={item.FeatureID}> <td> <input type="text" id={item.FeatureID} name="DisplayOrder" value={item.DisplayOrder} onChange={(ev) => { const newFeature = this.state.Feature.map((f) => { if (f.FeatureID === ev.target.id) { return { ...f, DisplayOrder: ev.target.value }; } return f; }); this.setState({ Feature: newFeature }); }} /> </td> <td>{item.DescriptionText}</td> <td>{item.FeatureText}</td> </tr> ))} </tbody> </table> <button type="submit" name="submit"> Update </button> </form> </div> ); } } export default EditFeatures;
关键说明
- 原始数据备份:通过
originalFeature保存初始数据,确保对比的基准是未修改的原始值,避免误判。 - 筛选逻辑:使用
filter和find方法精准定位修改过的条目,只提交必要数据,减少请求体积。 - 请求格式:提交的是修改后条目的数组,后端需要支持接收数组格式的请求体。
- 不可变状态更新:使用展开运算符创建新对象更新状态,符合React状态不可变的设计原则,避免意外的状态污染。
内容的提问来源于stack exchange,提问作者TestUser
相关产品推荐
相关产品推荐

