React Forms and Events
In this section, we will discuss how to use forms in React.
HTML form elements are different from other DOM elements in React because form elements naturally retain some internal state.
In HTML, form elements like <input>
, <textarea>
, and <select>
maintain their own state and update it based on user input. However, in React, mutable state is typically kept in the state property of components and can only be updated with the setState()
method.
A Simple Example
In the example, we set the input value to value = {this.state.data}. When the input value changes, we can update the state. We can use the onChange event to listen for changes in the input and modify the state.
React Example
class HelloMessage extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'Hello tutorialpro!'};
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>;
}
}
ReactDOM.render(
<HelloMessage />,
document.getElementById('example')
);
The above code will render an input element with a value of "Hello tutorialpro!" and update the value in response to user input via the onChange
event.
Example 2
In the following example, we will demonstrate how to use forms in child components. The onChange
method will trigger state updates and pass the updated value to the child component's input value to re-render the interface.
You need to create an event handler (handleChange) in the parent component 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 tutorialpro!'};
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}></Content>
</div>;
}
}
ReactDOM.render(
<HelloMessage />,
document.getElementById('example')
);
Select Dropdown
In React, instead of using the selected
attribute, the value
attribute is used on the root select
tag to indicate the selected option.
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">tutorialpro</option>
<option value="tb">Taobao</option>
<option value="fb">Facebook</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(
<FlavorForm />,
document.getElementById('example')
);
Multiple Forms
When you have multiple input elements to handle, you can add a name attribute to each element and let the handler function choose what to do based on the value of event.target.name
.
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>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
React Events
The following example demonstrates modifying data through an `onClick` event:
## React Example
class HelloMessage extends React.Component { constructor(props) { super(props); this.state = {value: 'Hello tutorialpro!'}; this.handleChange = this.handleChange.bind(this); }
handleChange(event) { this.setState({value: 'tutorialpro.org'}) } render() { var value = this.state.value; return <div> <button onClick={this.handleChange}>Click Me</button> <h4>{value}</h4> </div>; } } ReactDOM.render( <HelloMessage />, document.getElementById('example') );
When you need to update the parent component's **state** from a child component, you need to create an event handler (**handleChange**) in the parent component and pass it as a prop (**updateStateProp**) to your child component. Here is an example:
## 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 tutorialpro!'};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: 'tutorialpro.org'})
}
render() {
var value = this.state.value;
return <div>