首页 > 解决方案 > 基于动态复选框和文本输入的 setState 数组

问题描述

我正在开发一个在 react js 中的 UI,我正在从我从 API 获得的数据生成一个动态表,在左侧我有复选框,每个复选框都有一个特定的文本类型输入,这些输入是动态生成的就像声明的那样。我要存档的是,一旦选中用户复选框,我需要生成一个具有以下 4 个字段的对象isChecked(以检查复选框是否被选中),module_id(如果选中,则我需要获取模块 ID) , isUpdated(这是用于跟踪对特定输入文本所做的任何更改,如果不是,则应为零),discount_price(如果isUpdated为真,则我需要此值)。这些事情我试图通过setState在 react js 中实现。

上面定义的对象的必要性是为了在后端处理数据。根据我将编写查询的条件,我希望我对我的陈述问题很清楚。

我已经在类组件的构造函数中初始化了对象状态,我已经将 handleChange 方法与复选框和文本的输入绑定在一起,但是我遇到了错误TypeError: Cannot read property 'checked' of undefined,我想知道处理这种动态表单的最佳方法。

constructor(){
    super();
    this.state = {moduleData: [], modules : [] }
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

这是我的 handleChange 函数

handleChange(event) {
    const key = event.target.dataset.moduleindex;
    const modId =  event.target.dataset.moduleid;
    const inputKeyType = event.target.type;
    var is_updated = 1;
    if(inputKeyType == 'checkbox'){
      var inputChecked = !this.state.modules[key].checked;
      if (!this.state.modules[key].checked == false) {
        is_updated = 0;
      }
    } else {
      var inputChecked = true;
      is_updated = 1;
    }

    this.setState({
      modules: {
        ...this.state.modules,
        [key]: {
          ["isChecked"]: inputChecked,
          ["module_id"]: modId,
          ["isUpdated"]: is_updated,
          ["discount_price"]: event.target.value,
        }
      }
    });

  }

这是动态生成的表

const moduleRow =  modules.map((module, index) => (
    <tr key={module.id.toString()}>
              <th scope="row" width="" className='text-center' >
                <Input type="checkbox"
                className="checkbox"
                name="module_id"
                data-moduleindex = {index}
                data-moduleid = {module.id}
                checked={
                  this.state.modules[index]
                    ? this.state.modules[index].checked
                    : ""
                }
                onChange={this.handleChange}
                />
              </th>

              <td>
                {module.module_name}
              </td>

              <td>
                {module.module_short_code}
              </td>

              <td>
                {module.limits}
              </td>

              <td>
                { module.subscriptionInterval === 'monthly' ?  module.monthly_price  : module.annual_price }
              </td>

              <td>
                <Input
                type="text"
                name="discount_price"
                data-moduleindex = {index}
                id = {module.id}
                onChange={this.handleChange}
                value={
                  this.state.modules[index]
                    ? this.state.modules[index].discount_price
                    : ""
                }
                />
              </td>

              <td>
                {this.getStatus(module.status)}
              </td>

            </tr>
          ));

最后我想得到这样的对象数组

[
  0:{"isChecked":true, "module_id":2, "isUpdated" : 1, "discount_price": 5 },
  1:{"isChecked":false, "module_id":3, "isUpdated" : 1, "discount_price": 5 },
  2: {"isChecked":true, "module_id":8, "isUpdated" : 0, "discount_price": "" }
  ]

这可以实现还是我错过了什么?请帮忙

标签: javascriptarraysreactjsuser-interface

解决方案


你的问题就在这里;

if(inputKeyType == 'checkbox'){
  var inputChecked = !this.state.modules[key].checked;
  if (!this.state.modules[key].checked == false) {
    is_updated = 0;
  }
} 

this.state.modules初始化时将是一个空数组。您正在使用checked而不是isChecked. 所有复选框都以 false 开头,例如;

if(inputKeyType === 'checkbox'){
  var inputChecked = this.state.modules[key] ? !this.state.modules[key].isChecked : true
  if (inputChecked === false) {
    is_updated = 0;
  }
} else {
  var inputChecked = true;
  is_updated = 1;
}

this.state.modules也以数组开始,最终将其分配为setState. 因此,在您的构造函数中,我会将模块初始化为空对象

而且在输入类型中也需要这样做

 <Input type="checkbox"
                className="checkbox"
                name="module_id"
                data-moduleindex = {index}
                data-moduleid = {module.id}
                checked={
                  this.state.modules[index]
                    ? this.state.modules[index].isChecked
                    : ""
                }
                onChange={this.handleChange}
                />

推荐阅读