简体   繁体   中英

Typescript React handleChange() or handleSubmit() Form not working

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>
        );
      }


}

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:

Code Sandbox Link

(Typescript has been stripped out for this code sandbox but the important parts are easily transplantable)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM