React JS使用Axios实现表单不同input字段的多文件上传方案咨询
React Axios 多文件字段上传实现方案
问题根因
你当前代码所有文件选择结果都覆盖存入同一个image_file状态字段,提交时也仅追加了单个文件到FormData,只需要按输入框的name属性分别存储文件,提交时统一加入表单数据即可。
具体修改步骤
- 初始化state时补全全量表单字段存储结构,分别为3个文件字段预留存储位置
- 改造文件选择回调函数,根据输入框的
name属性存储对应文件 - 删除文件输入框的
value属性(React不允许手动设置受控文件输入框的value,会触发运行时错误) - 提交时将3个文件和其余普通文本字段全部追加到FormData中上传
修改后完整代码
import React from "react"; import axios from "axios"; import moment from "moment"; import "./calendar.css"; export default class Dashboard extends React.Component { constructor(props) { super(props); // 初始化完整state结构 this.state = { image_preview: "", // 存储三个文件的对象 files: { ScanReport: null, BloodReport: null, AntenatalCharts: null }, // 补全普通字段存储初始化 allValues: { bp: "", Weight: "" } }; this.onsubmbit = this.onsubmbit.bind(this); this.onChange = this.onChange.bind(this); } changeHandler = (e) => { this.setState({ allValues: { ...this.state.allValues, [e.target.name]: e.target.value }, }); }; // 改造文件选择回调,按name存储对应文件 onChange(e) { const file = e.target.files[0]; const fieldName = e.target.name; this.setState(prevState => ({ files: { ...prevState.files, [fieldName]: file } })); } onsubmbit = (e) => { e.preventDefault(); const formData = new FormData(); // 追加三个文件到formData Object.entries(this.state.files).forEach(([key, file]) => { if (file) formData.append(key, file); }) // 追加普通文本字段到formData Object.entries(this.state.allValues).forEach(([key, value]) => { formData.append(key, value); }) axios .post( "url/", formData, { headers: { Authorization: `token ${localStorage.getItem("token")}`, // 不需要手动设置Content-Type,axios会自动生成带boundary的正确值 }, } ) .then((res) => { console.log(`Success`, res.data); }) .catch((err) => { console.log(err); }); }; render() { return ( <> <form onSubmit={this.onsubmbit}> <div className="module-wrap" style={styles.module}> <h4>Upload Scan Report</h4> <input type="file" id="file" name="ScanReport" // accept="application/pdf" onChange={this.onChange} /> <h4>Upload Blood Report</h4> <input type="file" name="BloodReport" onChange={this.onChange} /> <h4>Upload Antenatal Charts</h4> <input type="file" name="AntenatalCharts" onChange={this.onChange} /> <h4>Enter Today BP</h4> <input type="text" name="bp" onChange={this.changeHandler} value={this.state.allValues.bp} /> <h4>Enter Todays Weight</h4> <input type="text" name="Weight" onChange={this.changeHandler} value={this.state.allValues.Weight} /> </div> <br /> <div> <button type="submit" style={styles.sbtn}> Submit </button> </div> </form> </> ); } }
可选优化
如果需要限制必填文件,可在提交前增加校验逻辑,判断三个文件是否都已选择,未选择时给出对应提示即可。
内容的提问来源于stack exchange,提问作者vivek kn
相关产品推荐
相关产品推荐

