Reputation: 447
I'm working on my first typescript react project so I'm a beginner trying to go through the loops. I have a form with 3 different select fields. For now what I'm trying to do is when you submit the form for it to display the values you selected.
With my code below if I were to change a select option lets say from yes to no, in my console for that handleChange
it will display null for that event. Also, when I submit the form for any field in which I have changed the select value it will display undefined in the alert.
I did notice that whenever I select a value in the drop down that the console reloads. So I'm not to sure if that's what is causing it to display a null.
I'm looking for the best way to store the selection that the user selected:
import * as React from 'react';
import styles from './TeacherSelector.module.scss';
import { ITeacherSelectorProps } from './ITeacherSelectorProps';
export default class TeacherSelector extends React.Component<ITeacherSelectorProps, {tenure: string, grade: string, location: string}> {
constructor(props) {
super(props);
this.state = {
tenure: 'yes',
grade: 'first',
location: 'new-york',
};
this.handleChangeTenure = this.handleChangeTenure.bind(this);
this.handleChangeGrade = this.handleChangeGrade.bind(this);
this.handleChangeLocation = this.handleChangeLocation.bind(this);
this.handleSubmit= this.handleSubmit.bind(this);
}
handleChangeTenure(event) {
console.log(event);
this.setState({tenure: event.target.tenure});
}
handleChangeGrade(event) {
console.log(event);
this.setState({grade: event.target.grade});
}
handleChangeLocation(event) {
this.setState({location: event.target.location});
}
handleSubmit(event) {
event.preventDefault();
alert('Tenure: ' + this.state.tenure + 'Grade: ' + this.state.grade + 'Location: ' + this.state.location);
}
public render(): React.ReactElement<ITeacherSelectorProps> {
return (
<div className={ styles.TeacherSelector }>
<div className={ styles.container }>
<div className={ styles.row }>
<div className={ styles.column }>
<form onSubmit={this.handleSubmit}>
<label>
Tenure (YES/NO):
<select name="tenure" value={this.state.tenure} onChange={(Val: any) => this.handleChangeTenure(Val)}>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
</label>
<label>
Teaching Grade Level
<select name="grade" value={this.state.grade} onChange={this.handleChangeGrade}>
<option value="first">first</option>
<option value="second">second</option>
<option value="third">third</option>
<option value="fourth">fourth</option>
</select>
</label>
<label>
Location
<select name="location" value={this.state.location} onChange={this.handleChangeLocation}>
<option value="new-york">New York</option>
<option value="queens">Queens</option>
<option value="new-jersey">New Jersey</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
</div>
);
}
}
Upvotes: 1
Views: 1327
Reputation: 1040
You just need to access the value
property on event.target
instead of grade
, location
or tenure
, as these do not exist.
handleChangeTenure(event) {
console.log(event);
this.setState({tenure: event.target.value}); // not .tenure
}
// repeat for other handle.. events
I would also recommend assigning that event value to a variable before using setState
on it. this.setState
happens asynchronously so by the time it fires, the synthetic event
is usually released which can cause issues. You can either assign value
to another value (my recommendation) or you can call event.persist()
to keep your event around until you don't need it anymore, though this comes with its own caveats.
More reading here: https://reactjs.org/docs/events.html#event-pooling
handleChangeTenure(event) {
// temp variable first = no more chrome console complaining about synthetic events
const { value } = event.target;
this.setState({tenure: value });
}
Here's a code sandbox link demonstrating the changes working:
(Typescript has been stripped out for this code sandbox but the important parts are easily transplantable)
Upvotes: 1