How do I edit multiple input controlled components in React?

后端 未结 9 438
[愿得一人]
[愿得一人] 2020-12-04 09:01

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

相关标签:
9条回答
  • 2020-12-04 09:41
    updatePrevData=(event)=>{
        let eventName=event.target.name;
       this.setState({
           ...this.state,
           prev_data:{
            ...this.state.prev_data,
            [eventName]:event.target.value
           }
    
       })
    
       console.log(this.state)
    
    }
    
    0 讨论(0)
  • 2020-12-04 09:44

    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>
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-04 09:46

    You can do it without duplicate code and easy way

    handleChange=(e)=>{
        this.setState({
            [e.target.id]:e.target.value
        })
    }
    
    
    <Form.Control type="text" defaultValue={this.props.allClients.name}  id="clientName"  onChange={this.handleChange}></Form.Control>
    <Form.Control type="email" defaultValue={this.props.allClients.email}  id="clientEmail"  onChange={this.handleChange}></Form.Control>
    
    0 讨论(0)
提交回复
热议问题