繁体   English   中英

反应 onChange 以处理状态对象

[英]React onChange to handle state objects

我有一个关于表单中的 React 状态和 onChange 事件的有趣问题。 在我的 React 组件中,我将信息存储在状态中,其中包括对象。 当用户输入更改时,我希望状态中的该对象的一部分发生更改。 例如,这是我正在谈论的状态:

this.state = {
      total: 0,
      email: '',
      creditCards: [],
      selectedCreditCard: {},
      billingAddresses: [],
      shippingAddresses: [],
      selectedBillingAddress: {},
      selectedShippingAddress: {},
    }

这是组件的状态,这是我的句柄更改功能:

  handleChange(event) {
    this.setState({
      [event.target.name]: event.target.value,
    })
  }

正如您可能知道的那样,这种类型的函数不适用于状态内的对象。 例如,当用户输入他们的信用卡号时,我希望 this.state.selectedCreditCard.creditCardNumber 发生变化。 当然,按照我的形式设置的方式:

<input
          type="text"
          name="selectedCreditCard.creditCardNumber"
          value={selectedCreditCard.creditCardNumber}
          onChange={(evt) => handleChange(evt)}
        />

传递给 onChange 的“名称”只是一个字符串,而不是指向状态中的一个对象中的键值的指针。 因此,除了解构 state 中的每个对象并将每个 key:value 直接放置在 state 中而不是对象中之外,此函数没有简单的方法可以工作; 这样做是有可能的,但是这样代码会变得非常麻烦。 我希望这一切都是有道理的。 有什么方法可以操作状态中的对象,并让表单传递指向对象中键的指针,而不是字符串? 谢谢。

我从您的描述中了解到您希望更新状态对象属性内的嵌套子项,如下所示

//default state
this.state = {
      total: 0,
      email: '',
      creditCards: [],
      selectedCreditCard: {},
      billingAddresses: [],
      shippingAddresses: [],
      selectedBillingAddress: {},
      selectedShippingAddress: {},
    }

更新为这样的东西

//state after handleEvent
{
      total: 0,
      email: '',
      creditCards: [],
      selectedCreditCard:{
       creditCardNumber:"102131313"
      }, 
      billingAddresses: [],
      shippingAddresses: [],
      selectedBillingAddress: {},
      selectedShippingAddress: {},
 }

如果是这样的话。 这是一个基于递归的解决方案,用于使用“.”创建嵌套对象 基于名称字符串。

  handleChange(event) {
    //use split function to create hierarchy. example:
    //selectedCreditCard.creditCardNumber -> [selectedCreditCard , creditCardNumber]
    const obj = this.generate(
      event.target.name.split("."),
      event.target.value,
      0
    );
    
    this.setState({ ...obj });
  }

  //use recursion to generate nested object. example
  //([selectedCreditCard , creditCardNumber] , 12 , 0) -> {"selectedCreditCard":{"creditCardNumber":"12"}} 
  generate(arr, value, index) {
    return {
      [arr[index]]:
        index === arr.length - 1 ? value : this.generate(arr, value, index + 1)
    };
  }

我已经创建了一个 codeandbox 演示供您在此处探索更多信息。 演示链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM