简体   繁体   中英

updating multiple inputs using onChange in a state array and display it onSubmit in React

I have a simple app where I have a form with multiple inputs and a button. I'd like to update the input values in a state array and display them on submit. I'm trying to use use onChange to update input values but I don't know how exactly I'd could possibly do this.

import React, { Component } from 'react';

class Info extends Component {
constructor(props) {
    super(props);
    this.state = {
        data: [],
        toggled: false,
    }
    this.onSubmit = this.onSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
}

//display html when saved
//when edited, bring back the inputs

onSubmit(e) {
    e.preventDefault();
}

handleChange(e) {
    console.log(e.target.value);
}

render() {
    return (
        <div className="info">
            <div>
                <h2 className="title"> Personal Information </h2>
            </div>
            <form action="#" noValidate onSubmit={this.onSubmit}>
                <div className='personal-info'>
                    <div>
                        <label htmlFor="fName"></label>
                        <input type="text" id="fName" name="fName" placeholder="First Name" onChange={this.handleChange}></input>
                    </div>
                    <div>
                        <label htmlFor="lName"></label>
                        <input type="text" id="lName" name="lName" placeholder="Last Name" onChange={this.handleChange}></input>
                    </div>
                    <div>
                        <label htmlFor="location"></label>
                        <input type="text" id="location" name="location" placeholder="Location" onChange={this.handleChange}></input>
                    </div>
                    <div>
                        <label htmlFor="email"></label>
                        <input type="email" id="email" name="email" placeholder="Email" onChange={this.handleChange}></input>
                    </div>
                    <div>
                        <label htmlFor="phone"></label>
                        <input type="tel" id="phone" name="phone" placeholder="phone" onChange={this.handleChange}></input>
                    </div>
                </div>
                <div className='personal-btn-groups'>
                   <button type="submit">Save</button>
                </div>
            </form>

        </div>
    )
  }
}

I've been always using query selectors to get input values in vanilla js and that seems to me easier way to do this But I understand that I'm not supposed be using it when working on React.

I do not know exactly how I'd update the values of inputs with the 'onChange' event handler and update them in a state array to display later on. But this is exactly what I'd like to do... Can anyone enlighten me please?

You need to use this.setState to store the values to react state. Here is an example of storing the input values to an object at this.state.form :

import React, { Component } from 'react'

export default class Info extends Component {
  constructor(props) {
    super(props)
    this.state = {
      data: [],
      toggled: false,
      form: {}
    }
    this.onSubmit = this.onSubmit.bind(this)
    this.handleChange = this.handleChange.bind(this)
  }

  //display html when saved
  //when edited, bring back the inputs

  onSubmit(e) {
    e.preventDefault()
  }

  handleChange(newForm) {
    this.setState({
      ...this.state,
      form: {
        ...this.state.form,
        ...newForm
      }
    })
  }

  render() {
    return (
      <div className="info">
        <div>
          <h2 className="title"> Personal Information </h2>
        </div>
        <form action="#" noValidate onSubmit={this.onSubmit}>
          <div className="personal-info">
            <div>
              <label htmlFor="fName"></label>
              <input
                type="text"
                id="fName"
                name="fName"
                placeholder="First Name"
                onChange={(e) =>
                  this.handleChange({
                    fName: e.currentTarget.value
                  })
                }
                value={this.state.form.fName}
              ></input>
            </div>
            <div>
              <label htmlFor="lName"></label>
              <input
                type="text"
                id="lName"
                name="lName"
                placeholder="Last Name"
                onChange={(e) =>
                  this.handleChange({
                    lName: e.currentTarget.value
                  })
                }
                value={this.state.form.lName}
              ></input>
            </div>
            <div>
              <label htmlFor="location"></label>
              <input
                type="text"
                id="location"
                name="location"
                placeholder="Location"
                onChange={(e) =>
                  this.handleChange({
                    location: e.currentTarget.value
                  })
                }
                value={this.state.form.location}
              ></input>
            </div>
            <div>
              <label htmlFor="email"></label>
              <input
                type="email"
                id="email"
                name="email"
                placeholder="Email"
                onChange={(e) =>
                  this.handleChange({
                    email: e.currentTarget.value
                  })
                }
                value={this.state.form.email}
              ></input>
            </div>
            <div>
              <label htmlFor="phone"></label>
              <input
                type="tel"
                id="phone"
                name="phone"
                placeholder="phone"
                onChange={(e) =>
                  this.handleChange({
                    phone: e.currentTarget.value
                  })
                }
                value={this.state.form.phone}
              ></input>
            </div>
          </div>
          <div className="personal-btn-groups">
            <button type="submit">Save</button>
          </div>
        </form>
      </div>
    )
  }
}

You have to store all input to data as object to avoid duplicate. onSubmit you simply take this.state and send it as the collected form data (I just logged the data here). For handleChange you need to make the handler dynamic so that it can work on as many form input as you wish. Hence, we are using e.target to access the current value entered and using the element's name (e.target.name) to save the data with it's value (e.target.value) to the state. Feel free to drop question if not clear.

import React, { Component } from 'react';

class Info extends Component {
  constructor(props) {
    super(props);
    this.state = {
        data: {},
        toggled: false,
    }
    this.onSubmit = this.onSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  onSubmit(e) {
    e.preventDefault();
    console.log(this.state);
  }

  handleChange(e) {
    this.setState({ ...this.state, data: {...this.state.data, [e.target.name]: e.target.value } })
  }

  render() {
    return (
        <div className="info">
            <div>
                <h2 className="title"> Personal Information </h2>
            </div>
            <form action="#" noValidate onSubmit={this.onSubmit}>
                <div className='personal-info'>
                    <div>
                        <label htmlFor="fName"></label>
                        <input type="text" id="fName" name="fName" placeholder="First Name" onChange={this.handleChange}></input>
                    </div>
                    <div>
                        <label htmlFor="lName"></label>
                        <input type="text" id="lName" name="lName" placeholder="Last Name" onChange={this.handleChange}></input>
                    </div>
                    <div>
                        <label htmlFor="location"></label>
                        <input type="text" id="location" name="location" placeholder="Location" onChange={this.handleChange}></input>
                    </div>
                    <div>
                        <label htmlFor="email"></label>
                        <input type="email" id="email" name="email" placeholder="Email" onChange={this.handleChange}></input>
                    </div>
                    <div>
                        <label htmlFor="phone"></label>
                        <input type="tel" id="phone" name="phone" placeholder="phone" onChange={this.handleChange}></input>
                    </div>
                </div>
                <div className='personal-btn-groups'>
                    <button type="submit">Save</button>
                </div>
            </form>

        </div>
      )
  }
}

export default Info;

you can use individual properties in state for storing values

import React, { Component } from 'react';

export default class Info extends Component {
constructor(props) {
    super(props);
    this.state = {}
}

//display html when saved
//when edited, bring back the inputs

onSubmit = (e) => {
    e.preventDefault();
    console.log('state', this.state)
}

handleChange = (e, key) => {
    // dynamic key
    this.setState({[key]: e.target.value})
}

render() {
    const { fName = "", lName = "", location = "", Email = "", phone = "" } = this.state;
    return (
        <div className="info">
            <div>
                <h2 className="title"> Personal Information </h2>
            </div>
            <form action="#" noValidate onSubmit={this.onSubmit}>
                <div className='personal-info'>
                    <div>
                        <label htmlFor="fName"></label>
                        <input type="text" value={fName} id="fName" name="fName" placeholder="First Name" onChange={e => this.handleChange(e, 'fName')}></input>
                    </div>
                    <div>
                        <label htmlFor="lName"></label>
                        <input type="text" value={lName} id="lName" name="lName" placeholder="Last Name" onChange={e => this.handleChange(e, 'lName')}></input>
                    </div>
                    <div>
                        <label htmlFor="location"></label>
                        <input type="text" value={location} id="location" name="location" placeholder="Location" onChange={e => this.handleChange(e, 'location')}></input>
                    </div>
                    <div>
                        <label htmlFor="email"></label>
                        <input type="email" value={Email} id="email" name="email" placeholder="Email" onChange={e => this.handleChange(e, 'Email')}></input>
                    </div>
                    <div>
                        <label htmlFor="phone"></label>
                        <input type="tel" value={phone} id="phone" name="phone" placeholder="phone" onChange={e => this.handleChange(e, 'phone')}></input>
                    </div>
                </div>
                <div className='personal-btn-groups'>
                   <button type="submit">Save</button>
                </div>
            </form>

        </div>
    )
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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