如何将ID和输入数组添加到我的状态?

时间:2018-09-22 16:31:34

标签: arrays reactjs input state

我正在尝试更新我的状态:

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;
    });
}

感谢您的帮助!

3 个答案:

答案 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)

我认为解决方案很简单。不要将idname属性放在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>
))

这样,我们可以在事件中使用idname,但是深度状态结构迫使我们这样写:

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个问题/缺点

  1. 值按索引存储在数组中-我们只有索引值对;

  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