I'm new to React and have run into a problem building a simple form component. There are four input fields and four matching onChange handlers. All of them are effectively identical:
handleEmailChange(event) {
this.setState({email: event.target.value});
}
handlePasswordChange(event) {
this.setState({password: event.target.value});
}
handleFirstNameChange(event) {
this.setState({firstName: event.target.value});
}
handleLastNameChange(event) {
this.setState({lastName: event.target.value});
}
render() {
return (
<div>
<label>Email: </label>
<input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleEmailChange} />
<label>Password: </label>
<input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange} />
<label>First name: </label>
<input type="text" name="firstName" placeholder="First name" value={this.state.firstName} onChange={this.handleFirstNameChange} />
<label>Last name: </label>
<input type="text" name="lastName" placeholder="Last name" value={this.state.lastName} onChange={this.handleLastNameChange} />
<input type="submit" value="Add User" onClick={this.handleSubmit} />
</div>
)
}
Three of these work just fine. The password handler, however, throws a TypeError exception "event.target is undefined" when the page tries to render. If I remove the handler and input element, the app renders. If I copy and paste one of the other handlers and inputs and change the relevant names, it still throws the exception. If I change the input type from "password" to "text" it still throws the exception. I cannot figure out why a seemingly identical piece of code is throwing this exception but every other piece of code like it works just fine.
In case it matters, the code for the entire component is
class AddUserForm extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
firstName: '',
lastName: ''
};
this.validate = this.validate.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleEmailChange = this.handleEmailChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange(this);
this.handleFirstNameChange = this.handleFirstNameChange.bind(this);
this.handleLastNameChange = this.handleLastNameChange.bind(this);
}
validate(user) {
return (user.email && user.password && user.firstName && user.lastName);
}
handleSubmit(event) {
let newUser = {
email: this.state.email,
password: this.state.password,
firstName: this.state.firstName,
lastName: this.state.lastName
};
if (AddUserForm.validate(newUser)) {
fetch(`http://localhost:3001/admin/addUser`, {
method: 'post',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
}),
body: JSON.stringify(newUser)
})
.then( res => {
const copy = [newUser].concat(this.state.users);
this.setState({users: copy});
})
}
event.preventDefault();
}
handleEmailChange(event) {
this.setState({email: event.target.value});
}
handlePasswordChange(event) {
this.setState({password: event.target.value});
}
handleFirstNameChange(event) {
this.setState({firstName: event.target.value});
}
handleLastNameChange(event) {
this.setState({lastName: event.target.value});
}
render() {
return (
<div>
<label>Email: </label>
<input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleEmailChange} />
<label>Password: </label>
<input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange} />
<label>First name: </label>
<input type="text" name="firstName" placeholder="First name" value={this.state.firstName} onChange={this.handleFirstNameChange} />
<label>Last name: </label>
<input type="text" name="lastName" placeholder="Last name" value={this.state.lastName} onChange={this.handleLastNameChange} />
<input type="submit" value="Add User" onClick={this.handleSubmit} />
</div>
)
}
}
this.handlePasswordChange = this.handlePasswordChange(this);. It should bethis.handlePasswordChange = this.handlePasswordChange.bind(this);