1

Here we have to write three functions to change the state of all input fields of form and in case if we have more fields e.g phone and address we have to write two more functions to change the state of those fields, i want to ask is there any way we can write only a single generic function to change the state of any field of this form rather than write separate function for every form field?

class SignUpForm extends React.Component {
        constructor() {
            super();
            this.state = {
                name: '',
                email: '',
                password: '',

            };
        }

        handleNameChange = (evt) => {
            this.setState({name: evt.target.value});
        }

        handleEmailChange = (evt) => {
            this.setState({email: evt.target.value});
        }

        handlePasswordChange = (evt) => {
            this.setState({password: evt.target.value});
        }
        render(){
            return(
                <form onSubmit={this.handleSubmit}>
                    <input
                        type="text"
                        placeholder="Enter Name"
                        value={this.state.name}
                        onChange={this.handleNameChange}
                    />
                    <input
                        type="text"
                        placeholder="Enter email"
                        value={this.state.email}
                        onChange={this.handleEmailChange}
                    />
                    <input
                        type="password"
                        placeholder="Enter password"
                        value={this.state.password}
                        onChange={this.handlePasswordChange}
                    />
                    <button disabled={isDisabled}>Sign up</button>
                </form>
            )
        }

    }
Llmsa
  • 13
  • 5

2 Answers2

5

You could use the following pattern:

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

You use handleChange like that:

<input
   type="text"
   placeholder="Enter Name"
   value={this.state.name}
   onChange={(event) => this.handleChange('name', event)}
/>
Vincent
  • 316
  • 1
  • 5
  • beat me to it. this [answer is related however](http://stackoverflow.com/questions/2462800/how-do-i-create-a-dynamic-key-to-be-added-to-a-javascript-object-variable) – Rico Kahler Mar 28 '17 at 09:42
1

There's an even cleaner way to write this using currying:

handleChange = type => event => this.setState({[type]: event.target.value})
<input
   type="text"
   placeholder="Enter Name"
   value={this.state.name}
   id="name"
   onChange={this.handleChange('name')}
/>

You could even use the element's ID attribute to avoid the instantiation of a new handler every time you render (since this.handleChange('name') would return a new instance of event => this.setState({name: event.target.value}) every render), and to avoid repeating yourself. However this may not be advisable since it means your element IDs must match your state keys.

handleChange = event => this.setState({[event.target.id]: event.target.value})
<input
   type="text"
   placeholder="Enter Name"
   value={this.state.name}
   id="name"
   onChange={this.handleChange}
/>
mezzode
  • 130
  • 3
  • 4
  • Nice one. But I get Warning: `controlId` is ignored on `` when `id` is specified. If I use react-bootstrap code like this – Jay Sep 14 '19 at 06:34