React动态生成input并存值到动态命名对象时旧值被置空问题求解
问题根因
你的代码存在3个核心逻辑问题:
setState是异步更新API,调用后不会立刻修改this.state的取值。你在handleAppend中先调用setState更新setting_append,紧接着读取this.state.setting_append时,拿到的是更新前的旧值,计数逻辑存在时序问题。handleAppend中遍历所有索引给setting_value赋值时,强制将已存在的字段值覆盖为null,直接清空了之前输入的内容。比如新增第二个输入框时,循环会同时给input_0、input_1赋值为null,直接覆盖了input_0之前输入的内容。handleValues中新增了非必要的if(value)判断,只有输入框有内容时才会更新state,若用户清空输入内容,对应字段不会同步更新,也会引发逻辑异常。
修复代码
1. 修复handleAppend逻辑
调整更新顺序,只给新增的输入框对应字段做初始化,不修改已有字段的取值,同时合并setState调用避免异步问题:
handleAppend = () => { // 先计算更新后的计数 const newAppendCount = this.state.setting_append + 1; // 拷贝原有存储对象,不直接修改state const newSettingValue = {...this.state.setting_value}; // 仅给新增的输入框对应的key做初始化,不碰已有字段 const newInputKey = `input_${this.state.setting_append}`; if (!newSettingValue.hasOwnProperty(newInputKey)) { newSettingValue[newInputKey] = null; } // 一次性更新所有state this.setState({ setting_append: newAppendCount, setting_value: newSettingValue }); }
2. 修复handleValues逻辑
移除非必要的取值判断,保证输入内容变化时(包括清空)都会同步更新state:
handleValues = (e, row) => { const value = e.target.value; const inputName = `input_${row}`; const newSettingValue = { ...this.state.setting_value, [inputName]: value }; this.setState({ setting_value: newSettingValue }); console.log(newSettingValue); }
可选优化
渲染逻辑中不需要先循环生成InputList数组再做映射,可以直接通过Array.from生成遍历序列,简化代码:
render() { return ( <> {Array.from({length: this.state.setting_append}, (_, index) => ( <Col key={index} md="6"> <Label>input {index}</Label> <Input onChange={(e) => {this.handleValues(e, index)}}/> </Col> ))} <Button onClick={this.handleAppend}>+</Button> </> ) }
内容的提问来源于stack exchange,提问作者Jack The Baker
相关产品推荐
相关产品推荐

