React OnChange for every field - is there a better way

965 views javascript
10

I call an API, get a payload and load it into state. Eg:

Payload : {
   id: 1,
   firstName: 'Craig',
   surname: 'Smith',
   anotherField: 'test data',
   ....
}

(Note, there are around 20 fields in real life)

On my react screen, I have the fields to display this data. At the moment, for every field, I have an onChange function. So:

this.firstnameOnChange = this.firstnameOnChange.bind(this);

and then the function:

firstnameOnChange() { ....}

Is there a simpler pattern to maybe lessen the amount of methods I need to create? Some sort of generic OnChange event that takes a name, and the value, which can then be used to update the state?

I can bind to something like:

myOnChange(fieldName, value) {
 // Somehow find the 'fieldName' in the state and update it's value with 'value'
}

Is this a valid pattern? Or is there a better way? Or should I stick to separate OnChange methods for each field?

If I can go generic, how would I find the name of the field in the state to update?

answered question

<input type="text" name="firstname" onChange={(e) => myOnChange('firstname', e.target.value}}

2 Answers

5

No this is not recommended to write onChange for every field. You can write a generic onChange method like this:

handleChange= name => event => {
 this.setState({payload: {...this.state.payload, [name] : event.target.value}});
  }

for example you have an input like this :

 <Input onChange={this.handleChange('firstName')} placeholder="Please Enter" />

PS here we are invoking handleChange directly so we use currying means a new instance being created for every invocation. There is another approach by extract name form event.target and create a name attribute in your input. Then you don't need to pass input name explicitly.

posted this
6

Since the state is an object that means you can update it's key and value. All you have to do is pass down the correct parameters to a generic update function which will update the state.

Here's one way you can do it: https://codesandbox.io/s/v382v6l483

You can bind this function to each field and keep your state updated.

Read more here on handling events and binding functions: https://reactjs.org/docs/handling-events.html

posted this

Have an answer?

JD

Please login first before posting an answer.