我正在尝试更新我的状态:
inputData: {
id: '',
inputArr: ['']
}
从我从州获得的表格中,我像这样生成他:
inner = arr.input.map((inputs, index) => (
<li key={index} name={index} id={inputs.id}>
<label>{inputs.inputLabel}</label>
<input
// value={inputs.inputValue}
type={inputs.inputType}
onChange={this.handleChangeInp}
/>
</li>
))
它将具有多个输入,因此我希望按顺序将其所有输入添加到数组中,以便以后可以提取它,但是我的handleChange函数似乎不起作用,有人知道为什么(我无法获得ID我正在通过事件传递,也不更新数组)?
handleChangeInp = e => {
const id = e.target.id;
console.log(`the id is ${id}`);
const index = Number(e.target.name);
const inputData = this.state.inputData.inputArr.map((ing, i) => {
console.log(i);
i == index ? e.target.value : ing;
});
}
感谢您的帮助!
答案 0 :(得分:0)
e.target
将引用元素并获取其道具,例如ID,名称等。您都需要在元素本身上具有道具。
要获取ID,您需要传递ID道具:
<input
id={inputs.id}
type={inputs.inputType}
onChange={this.handleChangeInp}
/>
现在,e.target.id
将获得输入ID。要获得名称,请执行与上面相同的操作。
在此示例中,e.target
是<input />
元素。并获得其属性,您只需添加道具。
答案 1 :(得分:0)
我认为解决方案很简单。不要将id
和name
属性放在li
元素上,而是将其添加到input
中。这样可以使您从name
获得e.target
。
已更新:基于其他研究:
React中的Synthetic onChange
事件不会传递id
属性。您需要提出另一个解决方案。如果需要将输入的名称和索引都保留在数组中,则可以将它们与特殊字符组合在一起,并在事件处理程序中对其进行拆分。回顾一下我创建的某些表单,我发现使用管道字符|
很容易,因为通常不使用它,但是即使如此,我仍然知道它将是字符串中的最后一个管道。
输入数组的更新图
inner = arr.input.map((inputs, index) => {
console.log({inputs});
return (
<li key={index}>
<label>{inputs.inputLabel}</label>
<input
name={inputs.id + "|" + index}
value={inputs.inputValue} /* try not commenting this out */
type={inputs.inputType}
onChange={this.handleChangeInp}
/>
</li>
)
});
更新了onChange处理程序
handleChangeInp = e => {
const name = e.target.name.split("|");
// index will be last element of array, pop it off
const index = Number(name.pop());
// join the name array back with the pipe character just in case it's used in the name
const id = name.join("|");
console.log(`the id is ${id}`);
console.log(`the index is ${index}`);
const inputData = this.state.inputData.inputArr.map((ing, i) => {
console.log(i);
i == index ? e.target.value : ing;
});
}
答案 2 :(得分:0)
第一次更新:
生成的输入的正确参数:
let inner = arr.input.map((inputs, index) => (
<li key={index} >
<label>{inputs.inputLabel}</label>
<input
id={index}
name={inputs.id}
// value={inputs.inputValue}
type={inputs.inputType}
onChange={this.handleChangeInp}
/>
</li>
))
这样,我们可以在事件中使用id
和name
,但是深度状态结构迫使我们这样写:
handleChangeInp = e => {
const id = e.target.id;
console.log(`the id is ${id}`);
const index = Number(e.target.id);
// deep state update
const newInputArr = this.state.inputData.inputArr.map((ing, i) => {
console.log(i, e.target.name);
return (i == index) ? e.target.value : ing;
});
const newInputData = {...this.state.inputData, inputArr: newInputArr}
this.setState({ inputData: newInputData }, ()=>{console.log(this.state.inputData)})
}
'works' ... 但是这种状态更新方法有2个问题/缺点:
值按索引存储在数组中-我们只有索引值对;
第二个问题更严重-它仅存储第一个值!对于地图使用(“搜索”),我们应该为每个索引初始化数组-否则不存储值
我的建议-使用对象(地图)存储值:
this.state = {
inputData: {
id: '',
inputArr: {}
}
};
和类似的处理程序:
handleChangeInp = e => {
const {name, value} = e.target;
console.log(name, value);
// deep state update
const newInputArr = {...this.state.inputData.inputArr,[name]:value};
const newInputData = {...this.state.inputData, inputArr: newInputArr}
this.setState({ inputData: newInputData }, ()=>{console.log(this.state.inputData)})
}
这样,我们就具有ID值对,并且仅适用于“触摸”字段。
工作example。
当然可以从状态(如果已定义)读取输入的值:
value={this.state.inputData.inputArr[inputs.id]
? this.state.inputData.inputArr[inputs.id] : ''}
// or
value={this.state.inputData.inputArr[inputs.id]===undefined ? ''
: this.state.inputData.inputArr[inputs.id] }
// f.e. when we're using type conversions
// and numerical value `0` could be used as valid input