首页 > 解决方案 > 如何处理多个输入是可编辑的

问题描述

我在反应中为多个输入添加了动态值,然后我尝试对其进行编辑,但它根本不可编辑。这是代码:

class Hotels extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [
        { id: 1, hotel: { name: "Sentido" } },
        { id: 2, hotel: { name: "Maris" } },
        { id: 3, hotel: { name: "Orka" } },
        { id: 4, hotel: { name: "Resort " } },
        { id: 5, hotel: { name: "Green " } },
        { id: 6, hotel: { name: "Maris" } },
        { id: 7, hotel: { name: "Nature " } },
        { id: 8, hotel: { name: "Diamond " } },
      ],
    };
  }

  render() {
    return data.map((item, i) => (
      <input
        name={`hotel__${i}.name`}
        onChange={this.handleChange}
        value={item.hotel.name}
        type="text"
      />
    ));
  }
  handleChange = (event) => {
    this.setState({
      [event.target.name]: event.target.value,
    });
  };
}
ReactDOM.render(<Hotels></Hotels>, document.getElementById("app"));

我不使用 defaultValue 属性并添加了一个 onChange 事件,但它不起作用!

标签: javascriptreactjs

解决方案


您的项目有一个id属性,因此不需要使用数组索引,例如name={`hotel__${i}.name`}我建议使用item.idid只是identifier的缩写,它应该标识一个资源。

有了这个建议,您必须传递一个资源标识符来handleChange识别要更改的资源。这可以通过多种方式完成。

  1. 将标识符或索引或项目id与事件一起传递给handleChange.

    onChange={(event) => this.handleChange(event, item.id)}
    
    // ...
    
    handleChange = (event, id) => {
      const name = event.target.value;
      this.setState((previous) => ({
        data: previous.data.map((item) => {
          if (item.id != id) return item;
          return { ...item, hotel: { name } };
          //    add `...item.hotel` ^ if hotel contains more attributes
          //    than just the name
        })
      }));
    };
    
  2. 这与第一个解决方案有很多共同之处。您可以使用已经提供handleChangeid创建一个 curried 版本。

    onChange={this.handleChange(item.id)}
    
    // ...
    
    handleChange = (id) => (event) => {
      // ...
    };
    

更新状态的解决方案不止这两种,但这些可能是最容易掌握的。

class Hotels extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [
        { id: 1, hotel: { name: "Sentido" } },
        { id: 2, hotel: { name: "Maris" } },
        { id: 3, hotel: { name: "Orka" } },
        { id: 4, hotel: { name: "Resort " } },
        { id: 5, hotel: { name: "Green " } },
        { id: 6, hotel: { name: "Maris" } },
        { id: 7, hotel: { name: "Nature " } },
        { id: 8, hotel: { name: "Diamond " } },
      ],
    };
  }

  render() {
    return this.state.data.map((item) => (
      <input
        key={item.id}
        name={`hotel__${item.id}.name`}
        onChange={this.handleChange(item.id)}
        value={item.hotel.name}
        type="text"
      />
    ));
  }
  
  handleChange = (id) => (event) => {
    const name = event.target.value;
    this.setState((previous) => ({
      data: previous.data.map((item) => {
        if (item.id != id) return item;
        return { ...item, hotel: { name } };
        //    add `...item.hotel` ^ if hotel contains more attributes
        //    than just the name
      })
    }));
  };
}

ReactDOM.render(<Hotels />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

上面的代码片段使用name={`hotel__${item.id}.name`},但如果您无法更改或更喜欢使用索引,则可以使用原始名称。


推荐阅读