【问题标题】:How can I add ID and inputs array to my state?如何将 ID 和输入数组添加到我的状态?
【发布时间】:2019-02-26 17:50:51
【问题描述】:

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

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

感谢您的帮助!

【问题讨论】:

  • 您问我们需要更多数据来回答的一个问题是关于更新您的阵列,inputData。您是否希望您的数组只是一个整数列表(即索引)?
  • InputData 它只是我在标签、类型和值标签中放入的三个字符串,它们真的与我正在谈论的问题有什么关系吗?
  • 是的。当您使用map 函数时,您将用一组新数据替换数组的内容。查看您的handleChangeInp 函数。你映射 inputData 并且 index 等于 i,你用单个字符串 e.target.value 替换。

标签: arrays reactjs input state


【解决方案1】:

e.target 将引用元素并获取它的道具,如 id、名称等。您都需要在元素本身上拥有道具。

要获取 id,您需要传递 id 道具:

<input
  id={inputs.id}
  type={inputs.inputType}
  onChange={this.handleChangeInp}
/>

现在,e.target.id 将获得输入 ID。要获取名称,请执行与上述相同的操作。

在本例中,e.target&lt;input /&gt; 元素。而要获取它的属性,你只需要添加道具。

【讨论】:

  • 我该怎么写?为什么是道具?我正在通过事件
【解决方案2】:

我认为解决方案很简单。不要将idname 属性放在li 元素上,而是将其添加到input。这应该允许您从e.target 获得name

更新:基于额外研究:

React 中的合成 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;
    });
}

【讨论】:

  • 我把它改成 Input 还是不行,我在函数中得到未定义的 ID =\
  • 我已经更新了。您需要查看传递给 map 函数的数据,以验证您获得了预期的值。我在map 函数中添加了console.log,这样您就可以看到inputs 的值。也许数据结构与您的预期不同。
  • 之后,为了彻底一点,在您的handleChangeInp 函数中记录e 的值,以便查看所有事件数据。
  • id 仍未定义 :(
  • 控制台中inputs 的值是多少?
【解决方案3】:

第一次更新:

生成输入的正确参数:

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' ... 但是这种状态更新方法有两个问题/缺点

  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-value 对,并且只适用于“接触”的字段。

工作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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-10
    • 2011-04-16
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多