如何在 React 中编辑多个输入控制组件? [英] How do I edit multiple input controlled components in React?

查看:19
本文介绍了如何在 React 中编辑多个输入控制组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个组件将联系人对象存储为状态 - {firstName: "John", lastName: "Doe", phone: "1234567890} 我想创建一个表单来编辑这个对象,但如果我想要输入保持原始接触参数的值,我需要让每个输入成为一个受控组件.但是,我不知道如何创建一个可以调整每个参数的handleChange函数,因为我的状态只持有{contact: {...}}. 以下是我目前拥有的 -

 getInitialState: function () {返回({联系:{}});},handleChange:函数(事件){this.setState({contact: event.target.value });},渲染:函数(){返回 (<div><input type="text" onChange={this.handleChange} value={this.state.contact.firstName}/><input type="text" onChange={this.handleChange} value={this.state.contact.lastName}/><input type="text" onChange={this.handleChange} value={this.state.contact.lastName}/>

);}

我希望在我的 handleChange 中我可以做类似的事情

 handleChange:函数(事件){this.setState({contact.firstName: event.target.value });}

解决方案

有一种简单"的方法可以做到这一点,还有一种智能"的方法.如果你问我,以聪明的方式做事并不总是最好的,因为以后可能更难和我一起工作.在这种情况下,两者都是可以理解的.

旁注:我要请您考虑的一件事是您是否需要更新 contact 对象,或者您可以直接保留 firstName 等在状态?也许你有很多组件状态的数据?如果是这种情况,最好将其拆分为更小的职责范围更小的组件.

简单"的方式

 changeFirstName: function (event) {const 联系 = this.state.contact;contact.firstName = event.target.value;this.setState({联系:联系});},更改姓氏:函数(事件){const 联系 = this.state.contact;contact.lastName = event.target.value;this.setState({联系:联系});},更改电话:功能(事件){const 联系 = this.state.contact;contact.phone = event.target.value;this.setState({联系:联系});},渲染:函数(){返回 (<div><input type="text" onChange={this.changeFirstName.bind(this)} value={this.state.contact.firstName}/><input type="text" onChange={this.changeLastName.bind(this)} value={this.state.contact.lastName}/><input type="text" onChange={this.changePhone.bind(this)} value={this.state.contact.phone}/>

);}

聪明"的方式

 handleChange: function (propertyName, event) {const 联系 = this.state.contact;联系[属性名称] = event.target.value;this.setState({联系:联系});},渲染:函数(){返回 (<div><input type="text" onChange={this.handleChange.bind(this, 'firstName')} value={this.state.contact.firstName}/><input type="text" onChange={this.handleChange.bind(this, 'lastName')} value={this.state.contact.lastName}/><input type="text" onChange={this.handleChange.bind(this, 'phone')} value={this.state.contact.lastName}/>

);}



更新:使用 ES2015+ 的相同示例

本节包含与上述相同的示例,但使用 ES2015+ 的功能.

要在浏览器中支持以下功能,您需要使用 Babel 使用例如转译您的代码预设 es2015反应,和插件 stage-0.

以下是更新的示例,使用对象解构 从国家获得联系方式,传播运算符创建一个更新的联系人对象而不是改变现有的对象,通过创建组件扩展 React.Component,并使用 箭头功能创建回调,这样我们就不必bind(this).

简单"的方式,ES2015+

class ContactEdit extends React.Component {changeFirstName = (事件) =>{const { 联系 } = this.state;const newContact = {...接触,名字:事件.目标.值};this.setState({ 联系人: newContact });}changeLastName = (事件) =>{const { 联系 } = this.state;const newContact = {...接触,姓氏:事件.目标.值};this.setState({ 联系人: newContact });}changePhone = (事件) =>{const { 联系 } = this.state;const newContact = {...接触,电话:event.target.value};this.setState({ 联系人: newContact });}使成为() {返回 (<div><input type="text" onChange={this.changeFirstName} value={this.state.contact.firstName}/><input type="text" onChange={this.changeLastName} value={this.state.contact.lastName}/><input type="text" onChange={this.changePhone} value={this.state.contact.phone}/>

);}}

智能"方式,ES2015+

请注意,handleChangeFor 是一个 柯里化函数:使用 propertyName 调用它会创建一个回调函数,该函数在调用时更新 [propertyName](新)状态中的联系人对象.

class ContactEdit extends React.Component {handleChangeFor = (propertyName) =>(事件) =>{const { 联系 } = this.state;const newContact = {...接触,[属性名称]:事件.目标.值};this.setState({ 联系人: newContact });}使成为() {返回 (<div><input type="text" onChange={this.handleChangeFor('firstName')} value={this.state.contact.firstName}/><input type="text" onChange={this.handleChangeFor('lastName')} value={this.state.contact.lastName}/><input type="text" onChange={this.handleChangeFor('phone')} value={this.state.contact.lastName}/>

);}}

I have a component that stores a contact object as state - {firstName: "John", lastName: "Doe", phone: "1234567890} I want to create a form to edit this object but if I want the inputs to hold the value of the original contact parameter, I need to make each input a controlled component. However, I don't know how to create a handleChange function that will adjust to each parameter because my state only holds {contact: {...}}. Below is what I currently have -

  getInitialState: function () {
    return ({contact: {}});
  },
  handleChange: function (event) {
    this.setState({contact: event.target.value });
  },
  render: function () {
    return (
        <div>
          <input type="text" onChange={this.handleChange} value={this.state.contact.firstName}/>
          <input type="text" onChange={this.handleChange} value={this.state.contact.lastName}/>
          <input type="text" onChange={this.handleChange} value={this.state.contact.lastName}/>
        </div>
      );
    }

I wish in my handleChange I can do something like

  handleChange: function (event) {
    this.setState({contact.firstName: event.target.value });
  }

解决方案

There's a "simple" way to do this, and a "smart" way. If you ask me, doing things the smart way is not always the best, because I may be harder to work with later. In this case, both are quite understandable.

Side note: One thing I'd ask you to think about, is do you need to update the contact object, or could you just keep firstName etc. directly on state? Maybe you have a lot of data in the state of the component? If that is the case, it's probably a good idea to separate it into smaller components with narrower responsibilities.

The "simple" way

  changeFirstName: function (event) {
    const contact = this.state.contact;
    contact.firstName = event.target.value;
    this.setState({ contact: contact });
  },
  changeLastName: function (event) {
    const contact = this.state.contact;
    contact.lastName = event.target.value;
    this.setState({ contact: contact });
  },
  changePhone: function (event) {
    const contact = this.state.contact;
    contact.phone = event.target.value;
    this.setState({ contact: contact });
  },
  render: function () {
    return (
      <div>
        <input type="text" onChange={this.changeFirstName.bind(this)} value={this.state.contact.firstName}/>
        <input type="text" onChange={this.changeLastName.bind(this)} value={this.state.contact.lastName}/>
        <input type="text" onChange={this.changePhone.bind(this)} value={this.state.contact.phone}/>
      </div>
    );
  }

The "smart" way

  handleChange: function (propertyName, event) {
    const contact = this.state.contact;
    contact[propertyName] = event.target.value;
    this.setState({ contact: contact });
  },
  render: function () {
    return (
      <div>
        <input type="text" onChange={this.handleChange.bind(this, 'firstName')} value={this.state.contact.firstName}/>
        <input type="text" onChange={this.handleChange.bind(this, 'lastName')} value={this.state.contact.lastName}/>
        <input type="text" onChange={this.handleChange.bind(this, 'phone')} value={this.state.contact.lastName}/>
      </div>
    );
  }



Update: Same examples using ES2015+

This section contains the same examples as shown above, but using features from ES2015+.

To support the following features across browsers you need to transpile your code with Babel using e.g. the presets es2015 and react, and the plugin stage-0.

Below are updated examples, using object destructuring to get the contact from the state, spread operator to create an updated contact object instead of mutating the existing one, creating components as Classes by extending React.Component, and using arrow funtions to create callbacks so we don't have to bind(this).

The "simple" way, ES2015+

class ContactEdit extends React.Component {

  changeFirstName = (event) => {
    const { contact } = this.state;
    const newContact = {
      ...contact,
      firstName: event.target.value
    };
    this.setState({ contact: newContact });
  }
  changeLastName = (event) => {
    const { contact } = this.state;
    const newContact = {
      ...contact,
      lastName: event.target.value
    };
    this.setState({ contact: newContact });
  }
  changePhone = (event) => {
    const { contact } = this.state;
    const newContact = {
      ...contact,
      phone: event.target.value
    };
    this.setState({ contact: newContact });
  }

  render() {
    return (
      <div>
        <input type="text" onChange={this.changeFirstName} value={this.state.contact.firstName}/>
        <input type="text" onChange={this.changeLastName} value={this.state.contact.lastName}/>
        <input type="text" onChange={this.changePhone} value={this.state.contact.phone}/>
      </div>
    );
  }
}

The "smart" way, ES2015+

Note that handleChangeFor is a curried function: Calling it with a propertyName creates a callback function which, when called, updates [propertyName] of the (new) contact object in the state.

class ContactEdit extends React.Component {

  handleChangeFor = (propertyName) => (event) => {
    const { contact } = this.state;
    const newContact = {
      ...contact,
      [propertyName]: event.target.value
    };
    this.setState({ contact: newContact });
  }

  render() {
    return (
      <div>
        <input type="text" onChange={this.handleChangeFor('firstName')} value={this.state.contact.firstName}/>
        <input type="text" onChange={this.handleChangeFor('lastName')} value={this.state.contact.lastName}/>
        <input type="text" onChange={this.handleChangeFor('phone')} value={this.state.contact.lastName}/>
      </div>
    );
  }
}

这篇关于如何在 React 中编辑多个输入控制组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆