React(axios)实现PUT请求时Modal表单预填充及更新逻辑问题
React 编辑Modal预填充+更新功能修复方案
你现在代码的核心问题有3个:
- 点表格里的Update按钮直接触发PUT请求,既没打开Modal,也没把待编辑条目数据存入组件状态
- 表单输入框用了
defaultValue,这是非受控组件属性,仅在组件首次渲染时生效,后续状态更新不会同步到输入框,自然没法做预填充 - 新增、编辑的Modal触发逻辑没做区分,关闭Modal、提交成功后的列表刷新逻辑也缺失
逐块修改代码
1. 拆分Modal打开逻辑,区分新增/编辑场景
保留原有给新增按钮用的showModal,打开时清空表单状态;额外加一个编辑场景的Modal触发方法,接收当前行的完整条目数据,存入状态:
// 新增场景打开Modal:清空表单 showModal = () => { this.setState({ show: true, id: '', nameEn: '', nameRu: '' }) } // 编辑场景打开Modal:预填充当前行数据 showEditModal = (style) => { this.setState({ show: true, id: style.id, nameEn: style.nameEn, nameRu: style.nameRu }) }
对应修改表格里Update按钮的点击事件,不要直接调提交方法,改成触发编辑Modal、传入当前行数据:
<td> <button className='btn btn-warning' onClick={() => this.showEditModal(style)} > Update </button> </td>
2. 把表单输入框改成受控组件
把所有Form.Control上的defaultValue属性换成value,绑定对应状态值,这样状态更新时输入框内容会自动同步,预填充才能生效:
<Form.Control type="text" value={this.state.nameEn} name='nameEn' onChange={this.handleChange} /> <Form.Control type="text" name='nameRu' value={this.state.nameRu} onChange={this.handleChange} />
3. 修正提交逻辑
首先把提交按钮上多余的onClick={this.hideModal}删掉——这个逻辑会导致不管提交成不成功,点按钮就直接关Modal,关闭操作放到提交成功回调里做就行:
<Button variant="primary" type='submit'> {this.state.id ? "Save updates": "Add New"} </Button>
然后修改handleUpdate方法,直接从状态里取之前存好的条目id,不需要额外从参数传,提交成功后刷新列表、关闭Modal:
handleUpdate = (event) => { event.preventDefault(); const style = { nameEn: this.state.nameEn, nameRu: this.state.nameRu, } axios.put(`http://127.0.0.1:8000/api/v1/styles/${this.state.id}/`, style) .then(res => axios.get("http://127.0.0.1:8000/api/v1/styles/")) .then(res => { this.setState({ styles: res.data, show: false }) }) .catch((err) => { console.log(err.response) console.log(err.message) }); }
顺便给原来的handleSubmit新增方法也补上提交成功后刷新列表、关Modal的逻辑,不然新增完表格不会自动更新:
handleSubmit = event => { event.preventDefault(); const style = { nameEn: this.state.nameEn, nameRu: this.state.nameRu, }; axios.post('http://127.0.0.1:8000/api/v1/styles/', style) .then(res => axios.get("http://127.0.0.1:8000/api/v1/styles/")) .then(res => { this.setState({ styles: res.data, show: false }) }).catch((err) => { console.log(err.response) console.log(err.message) }); }
另外你constructor里重复绑定了showModal和hideModal的this,后面你已经用箭头函数定义这两个方法了,constructor里的两行bind代码可以直接删掉,不会有this指向问题。
改完后的运行逻辑
- 点Add按钮:清空表单状态打开Modal,输入内容提交走POST新增逻辑
- 点行内Update按钮:把当前条目的id、多语言名称存入状态,打开Modal后输入框自动填充原有内容,修改后提交走PUT更新逻辑
- 不管新增还是更新,提交成功后会自动拉取最新列表、关闭Modal,表格内容实时同步
内容的提问来源于stack exchange,提问作者Apollo Vostok
相关产品推荐
相关产品推荐

