George Welder
George Welder

Reputation: 4045

Using a single handleInputChange method to for multiple input fields (React)

I have a form, in React"

render() {
    return (
      <div>
        <form onSubmit={this.onFormSubmit}>
          <input
            value={this.state.first}
          />

          <input
            value={this.state.second}
          />

          <input
            value={this.state.third}
          />
           //.... many more
        </form>
     //...
)}

My handleInputChange usually looks like this:

  handleInputChange(e) {
    this.setState({value: e.target.value });
  }

Now, since I have many different input fields, i would normally do many different handleInputChange methods. However, all of these handle input change things basically do the same: they set the state anew, according to which input field is currently edited.

How could I, instead of writing three handleInputChange methods each doing something like:

  handleInputChangeFirst(e) {
    this.setState({first: e.target.value });
  }
  handleInputChangeSecond(e) {
    this.setState({second: e.target.value });
  }

... do all of this with one single handleInputChange, which then checks which value needs to be updated? How can i let handleInputChange know about the input field that is being edited and react accordingly?

Upvotes: 1

Views: 7934

Answers (2)

Abi
Abi

Reputation: 21

Correct me if I'm wrong, but wouldn't the above method return a new function for each render? So if you pass these handlers down to a child component then they'd be seen as an updated prop every time instead of the same prop (cause it's a new function every render), and cause an unwanted re-render of the child. One of the reasons inline functions are hated in the render method.

Here's another solution I saw somewhere online:

handleInputChange = event => {
  const { name, value } = event.target;
  this.setState({
    [name]: value
  });
}

And the input element:

<input name="first" value={this.state.first} onChange={this.handleInputChange} />

Name might not be the best attribute to use, but you get the point

Upvotes: 2

Bertrand Marron
Bertrand Marron

Reputation: 22210

You could have a generic handleInputChange method:

handleInputChange(property) {
  return e => {
    this.setState({
      [property]: e.target.value
    });
  };
}

That you’d use as such:

<input
  value={this.state.first}
  onChange={this.handleInputChange('first')}
/>

Upvotes: 3

Related Questions