Let's work on the Input component a little more. When a user types inside the input box, it'd be great for user experience to validate the user's input and display an indicator next to it. The indicator can be colored green if the input is valid, or red if not.
Therefore, our Input component needs to:
- Listen and handle events, so that it can validate the input when the value changes.
- Maintain the state, so the component can persist the result of the validation.
Currently, our Input component is defined in the functional components style. This is preferred but it is limited in features; it cannot hold the state. Therefore, let's first convert the Input component into a class component:
class Input extends React.Component {
render() {
return <label>{this.props.label}<input type={this.props.type} /></label>
}
}
Next, we can give each instance of the Input component a state. A state in React is simply a key-value store (that is, an object) that is internal (private) to the instance. For us, we will use the state to hold information about whether the input is valid.
We can define an initial state of the component inside the component class' constructor method, which is a special method that is called when the class is instantiated with the new keyword.
class Input extends React.Component {
constructor() {
super();
this.state = { valid: null }
}
render () { ... }
}
We are setting the state property valid to null, because before the user has entered anything, we don't want to say that it is valid or invalid.
Next, we need to add event listeners to the input HTML element. Event listeners in JSX are similar to the HTML ones, except that they are camelCase instead of lowercase. For instance, an onchange listener in HTML would be onChange. The value of the event handler prop should be an event handler function. Update the input element inside the label tag to include the onChange prop.
render() {
return <label>{this.props.label}<input onChange={this.validate} ... /></label>
}
Now, whenever the value of the input changes, this.validate is invoked, passing in the event object as its only argument. Since this method doesn't exist yet, we must now define it.