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