React Forms and Events

In this chapter, we will discuss how to use forms in React.

HTML form elements differ from other DOM elements in React, because form elements naturally retain some internal state.

In HTML, form elements such as <input>, <textarea>, and <select> maintain their own state and update based on user input. But in React, mutable state is usually stored in the component's state property, and can only be updated with the setState() method.

A simple example

In the example, we set the input valuevalue = {this.state.data}. When the input value changes, we can update the state. We can useonChangeevent to listen for changes in input and modify the state.

React example

class HelloMessage extends React.Component { constructor(props) { super(props); this.state = {value: 'Hello Example!'}; this.handleChange = this.handleChange.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } render() { var value = this.state.value; return <div> <input type="text" value={value} onChange={this.handleChange} /> <h4>{value}</h4> </div>; } } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <HelloMessage /> );

Try it yourself »

The above code will render an input element with the value "Hello Example!" and respond to update the user-entered value through the onChange event.

Example 2

In the following example, we will demonstrate how to use forms on a child component.onChangeThe method will trigger the state update and pass the updated value to the child component's input field'svaluevalue to re-render the interface.

You need to create an event handler in the parent component (handleChange) and pass it as a prop (updateStateProp) to your child component.

React example

class Content extends React.Component { render() { return ( <div> <input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp} /> <h4>{this.props.myDataProp}</h4> </div> ); } } class HelloMessage extends React.Component { constructor(props) { super(props); this.state = { value: 'Hello Example!' }; this.handleChange = this.handleChange.bind(this); } handleChange(event) { this.setState({ value: event.target.value }); } render() { var value = this.state.value; return ( <div> <Content myDataProp={value} updateStateProp={this.handleChange} /> </div> ); } } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<HelloMessage />);

Try it yourself »

Select dropdown menu

In React, you don't use the selected attribute; instead, you use the value attribute on the root select tag to indicate the selected item.

React example

class FlavorForm extends React.Component { constructor(props) { super(props); this.state = {value: 'coconut'}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } handleSubmit(event) { alert('Your favorite flavor is: ' + this.state.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Choose your favorite website <select value={this.state.value} onChange={this.handleChange}> <option value="gg">Google</option> <option value="rn">Example</option> <option value="tb">Taobao</option> <option value="fb">Facebook</option> </select> </label> <input type="submit" value="Submit" /> </form> ); } } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <FlavorForm /> );

Try it yourself »

Multiple forms

When you need to handle multiple input elements, you can add a name attribute to each element, so that the handler function, based on theevent.target.namevalue, decides what to do.

React example

class Reservation extends React.Component { constructor(props) { super(props); this.state = { isGoing: true, numberOfGuests: 2 }; this.handleInputChange = this.handleInputChange.bind(this); } handleInputChange(event) { const target = event.target; const value = target.type === 'checkbox' ? target.checked : target.value; const name = target.name; this.setState({ [name]: value }); } render() { return ( <form> <label> Leave: <input name="isGoing" type="checkbox" checked={this.state.isGoing} onChange={this.handleInputChange} /> </label> <br /> <label> Number of visitors: <input name="numberOfGuests" type="number" value={this.state.numberOfGuests} onChange={this.handleInputChange} /> </label> </form> ); } }

Try it yourself »

React events

The following example demonstrates modifying data through the onClick event:

React example

class HelloMessage extends React.Component { constructor(props) { super(props); this.state = {value: 'Hello Example!'}; this.handleChange = this.handleChange.bind(this); } handleChange(event) { this.setState({value: 'Example'}) } render() { var value = this.state.value; return <div> <button onClick={this.handleChange}>Click me</button> <h4>{value}</h4> </div>; } } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <HelloMessage /> );

Try it yourself »

When you need to update the parent component'sstatestate, you need to create an event handler in the parent component (handleChange) and pass it as a prop (updateStateProp) to your child component.

React example

class Content extends React.Component { render() { return <div> <button onClick = {this.props.updateStateProp}>Click me</button> <h4>{this.props.myDataProp}</h4> </div> } } class HelloMessage extends React.Component { constructor(props) { super(props); this.state = {value: 'Hello Example!'}; this.handleChange = this.handleChange.bind(this); } handleChange(event) { this.setState({value: 'Example'}) } render() { var value = this.state.value; return <div> <Content myDataProp = {value} updateStateProp = {this.handleChange}></Content> </div>; } } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <HelloMessage /> );

Try it yourself »
Other extensions