Controlled Components

In HTML, form elements such as <input>, <textarea>, and <select> typically maintain their own state and update it based on user input. In React, mutable state is typically kept in the state property of components, and only updated with setState(). We can combine the two by making the React state be the "single source of truth". Then the React component that renders a form also controls what happens in that form on subsequent user input. An input form element whose value is controlled by React in this way is called a controlled component.

With a controlled component, the input’s value is always driven by the React state.


    class NameForm extends React.Component {
        constructor(props) {
            super(props);
            this.state = { nameValue: '', essayValue: '', genderValue: 'male', isGoing: true, numberOfGuests: 2 };
            this.handleNameChange = this.handleNameChange.bind(this);
            this.handleEssayChange = this.handleEssayChange.bind(this);
            this.handleGenderChange = this.handleGenderChange.bind(this);
            this.handleInputChange = this.handleInputChange.bind(this);
            this.handleSubmit = this.handleSubmit.bind(this);
        }

        handleNameChange(event) { this.setState({nameValue: event.target.value}); }
        handleEssayChange(event) { this.setState({essayValue: event.target.value}); }
        handleGenderChange(event) { this.setState({value: event.target.value}); }
        handleInputChange(event) {
          const target = event.target;
          const value = target.type === 'checkbox' ? target.checked : target.value;
          const name = target.name;
          this.setState({ [name]: value });
        }

        handleSubmit(event) { event.preventDefault(); }

        render() {
            return (
                <form onSubmit={this.handleSubmit}>
                    <label> Name: <input type="text" value={this.state.nameValue} onChange={this.handleNameChange} /> </label>
                    <label> Essay: <textarea value={this.state.essayValue} onChange={this.handleEssayChange} /> </label>
                    <label>
                        Gender: <select value={this.state.genderValue} onChange={this.handleGenderChange}> <option value="male">Male</option> >option value="female">Female</option> </select>
                    </label>
                    <input type="submit" value="Submit" />
                    <label>
                        Is going:
                        <input name="isGoing" type="checkbox" checked={this.state.isGoing} onChange={this.handleInputChange} />
                    </label>
                    <label>
                        Number of guests:
                        <input name="numberOfGuests" type="number" value={this.state.numberOfGuests} onChange={this.handleInputChange} />
                    </label>
                </form>
          );
        }
    }
        

Uncontrolled Components

// will learn later