【问题标题】:React input setState for array of objects为对象数组反应输入 setState
【发布时间】:2018-12-14 01:51:38
【问题描述】:

查看表格以编辑Google Contacts 中的电话号码。

假设我的状态如下:

    this.state = {
        phones: [
            {
                country: 'US',
                label: 'Home',
                number: '555'
            }
        ],

    };

我的 HTML 看起来像一个循环并简化为所有文本输入:

<input type="text" value={this.state.phones[index].country} onChange={this.handleChange} />
<input type="text" value={this.state.phones[index].number} onChange={this.handleChange} />
<input type="text" value={this.state.phones[index].label} onChange={this.handleChange} />

您将如何实现handleChange 来调用setState,同时支持它是一个数组,并且数组中的每个项目都有多个属性这一事实?

我在其他问题中看到了一些答案,但没有一个完整的答案。

【问题讨论】:

  • 如果我正确地回答了你的问题,你应该创建一个组件 Phone 来处理它自己的状态

标签: javascript reactjs forms


【解决方案1】:

您可以执行以下操作,还可以创建一个Phone 组件。

class Phone extends React.Component {

  render() {
    return (
      <div className="App">
        <p>{this.props.label}</p>
        <input
          type="number"
          onChange={this.props.updateNumber}
          value={this.props.number}
        />
      </div>
    );
  }
}

class App extends React.Component {
  state = {
    phones: [
      {
        name: "US",
        number: ""
      },
      {
        name: "UK",
        number: ""
      }
    ]
  };

  updateNumber = (e, index) => {
    const phones = this.state.phones;
    phones[index].number = e.target.value;
    this.setState({
      phones
    });
  };

  render() {
    return (
      <div className="App">
        {this.state.phones.map((phone, i) => {
          return (
            <Phone
              updateNumber={e => {
                this.updateNumber(e, i);
              }}
              number={this.state.phones[i].number}
              label={phone.name}
            />
          );
        })}
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='root'></div>

【讨论】:

  • 有趣。这被认为是最佳做法吗?另外,(在这里对不起新手),但是状态会向上传播吗?归根结底,实际的表单在父组件中,它将是将更新的用户配置文件发送到服务器等。
  • 我相信这被认为是正确的做法。这是以前让我抓狂的东西。我知道您将数据从父组件发送到服务器是什么意思。您可以将数据从子组件传递回父组件
  • 所以你的意思是,子组件将在其父组件上调用一个函数(它作为输入接收)。我想我们在这里回到部分答案,因为在我们的例子中,我们有一个子组件数组。那么子组件如何更新数组中的正确项呢?
  • 你知道吗,我正在看这里,因为我现在知道你的意思——我想我也有点困惑——我会尝试破解它。当您尝试在父级中设置状态时,这是一个奇怪的状态 - 这就是它被捕获的地方
  • @NathanH 我认为更新后的答案就是你要找的
【解决方案2】:

2 个选项

  1. 按照 Paul Fitzgerald 的建议,制作一个具有自己状态的 Phone 组件。

  2. 将索引添加到data-index 属性并检查handleChange 中的值。

示例 2:

<input type="text" value={this.state.phones[index].country} data-index="0" onChange={this.handleChange} />
<input type="text" value={this.state.phones[index].number} data-index="0" onChange={this.handleChange} />
<input type="text" value={this.state.phones[index].label} data-index="0" onChange={this.handleChange} />

然后在handleChange:

handleChange(e) {
    ...
    const i = e.target.dataset.index;
    ...
}

【讨论】:

  • 关于选项 (2),这对我有什么帮助?获取索引并不是真正的问题,我的意思是,我如何在setState 中更新这些信息?
  • 哦,对了,更新状态数组中的单个对象的方法很少,但这是一个不同的问题。保罗的回答确实是更好的选择。
猜你喜欢
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 2018-08-29
  • 2020-07-30
  • 2021-05-17
相关资源
最近更新 更多