使用相同名称属性反应多个输入字段会触发不同输入中的多个更新

时间:2017-09-19 07:23:09

标签: forms reactjs dictionary input

所以,问题出在下面。

  handleBankAccountInput = (e, key) => {
let name = e.target.name;
let value = e.target.value;
let validation = e.target.key;
let bankAccounts = {...this.state.bankAccounts};
let ibanValid = bankAccounts[key].validationState.iban;
let banknameValid = bankAccounts[key].validationState.bankname;
bankAccounts[key][name] = value;

switch(validation) {
  case 'iban':
    ibanValid = IBAN.isValid(value); // true
    bankAccounts[key].fieldValidationErrors.iban = ibanValid ? '' : ' is invalid IBAN';
    bankAccounts[key].validationState.iban = ibanValid ? 'success' : 'error';
    console.log("why validate all iban of bankAccounts of key: " + key );
    console.log(bankAccounts[key]);

    break;
  case 'bankname':
    banknameValid = value.length >=1; // true
    bankAccounts[key].fieldValidationErrors.bankname = banknameValid ? '' : ' is invalid bankname';
    bankAccounts[key].validationState.bankname = banknameValid ? 'success' : 'error';
    console.log("why validate all bankname of bankAccounts of key: " + key );
    console.log(bankAccounts[key]);
    break;
  default:
    break;
}

// bankAccounts[key] = bankAccount;
this.setState({bankAccounts: bankAccounts}, this.validateForm);
bankAccounts = {};
}

问题:

  

该行' bankAccounts [key] .fieldValidationErrors.iban =   ibanValid? '' :'是无效的IBAN&#39 ;; '由其他输入触发   具有相同的名称属性。

  addBankAccountInput = () => {
let bankAccounts = {...this.state.bankAccounts};
// add in our new menu
let bankAccount = {...this.state.bankAccount};
bankAccount['iban'] = '';
bankAccount['bankname'] = '';
bankAccount['validationState']['iban'] = '';
bankAccount['validationState']['bankname'] = '';
bankAccount['formErrors']['iban'] = '';
bankAccount['formErrors']['bankname'] = '';
bankAccount['fieldValidationErrors']['iban'] = '';
bankAccount['fieldValidationErrors']['bankname'] = '';

let accountnum = 0;
if(bankAccounts) {
  Object.keys(bankAccounts).map((key) => accountnum++ );
}

bankAccounts[accountnum] = bankAccount;
this.setState({ bankAccounts: bankAccounts });
bankAccount = {};
bankAccounts = {};
}

这是我添加空bankAccount输入的方式。

  renderBankAccountInput = (key) => {
return (
  <div key={key}>
    <FormGroup controlId={'formHorizontalBankAccount'+key} validationState={this.state.bankAccounts[key].validationState.iban}>
      <Col componentClass={ControlLabel} sm={2}>
        IBAN
      </Col>
      <Col sm={10}>
        <FormControl type="text" name={'iban'+key} key='iban' value={this.state.bankAccounts[key].iban} placeholder="iban" onChange={(e) => this.handleBankAccountInput(e, key)} />
      </Col>
      <FormControl.Feedback />
      <HelpBlock>{this.state.bankAccounts[key].formErrors.iban}</HelpBlock>
    </FormGroup>
    <FormGroup controlId={'formHorizontalBankAccount' + key} validationState={this.state.bankAccounts[key].validationState.bankname}>
      <Col componentClass={ControlLabel} sm={2}>
        Bankname
      </Col>
      <Col sm={10}>
        <FormControl type="text" name={'bankname'+key} key='bankname' value={this.state.bankAccounts[key].bankname} placeholder="Bank name" onChange={(e) => this.handleBankAccountInput(e, key)} />
      </Col>
      <FormControl.Feedback />
      <HelpBlock>{this.state.bankAccounts[key].formErrors.bankname}</HelpBlock>
    </FormGroup>
  </div>
)
}

这就是我渲染输入的方式。

喜欢这个。

银行账户

    {Object.keys(this.state.bankAccounts).map(this.renderBankAccountInput)}
    { this.state.bankAccounts.length < 1 &&
      <HelpBlock>You should provide at least one bank account</HelpBlock>
    }
    <button
      onClick={(e) => {
        e.preventDefault();
        this.addBankAccountInput();
      }}
    >Add Bank Account</button>`

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

这是由于React的棘手和头痛问题。您正在使用数组索引作为key到此行<div key={key}>映射的组件。它在更新数组时使React感到困惑,属性属于哪个组件并导致不可预测的结果。

您可以在SO answer中参考此Preact以及有关此问题的更多解释,这是React的替代方案。这个解释也可以在React中应用。

解决方案:

  • 为您的组件列表生成一个uuid。我的图书馆提供此功能,例如lodash-uuidshortid
  • 在您的情况下,您可以使用bankAccounts[key][iban]作为组件密钥。