React-Champ: Part II: When and how to use uncontrolled components
In my previous post(Controlled vs Uncontrolled Components), I discussed the implementation and benefits of controlled components in React. In this post, I will tell you when it makes sense to use uncontrolled components.
You cannot go wrong when you use controlled components. But sometimes it can be overkill. You can choose to make your components uncontrolled if you answer “yes” to the following questions.
- Your form is very simple and doesn’t need any instant validation?
- Even if any validations are needed, they are done only when the form is submitted?
- Values need to be retrieved only on “submit”. No fields are dependent on any other field(s)?
How to implement uncontrolled components?
Before going forward, you will first need to get familiar with “Refs” in React. Basically, refs provide a way to access React elements or DOM nodes created in the render method.
Step 1: Get a “ref” for the input field in the constructor
Step 2: Assign the ref to the input field in the render method
Step 3: Access the value of the input field using the same ref instance
You can find the complete code in this GitHub repo(Branch: uncontrolled-components)
Step 1: Get a “ref” for the input field in the constructor
constructor(props) {
super(props);
this.refName = React.createRef();
}
Step 2: Assign the ref to the input field in the render method
render() {
return (
<div>
...
<input
ref={this.refName}
type="text"
placeholder="Name"
/>
...
<Button bsStyle="primary" onClick={this.handleSubmit}>Submit</Button>
...
</div>
);
}
Step 3: Access the value of the input field using the same ref instance
handleSubmit = () => {
const name = this.refName.current.value;
if (name.length > 0) {
alert(`Username ${name} is approved`);
} else {
alert('Validation error: Username cannot be empty');
}
}
Complete example
import React, {Component} from 'react';
import {
Row,
Col,
FormGroup,
ControlLabel,
FormControl,
Button
} from 'react-bootstrap';class UncontrolledComponentForm extends Component {
constructor(props) {
super(props);
this.refName = React.createRef();
}
handleSubmit = () => {
const name = this.refName.current.value;
if (name.length > 0) {
alert(`Username ${name} is approved`);
} else {
alert('Validation error: Username cannot be empty');
}
}
render() {
return (
<div>
<Row>
<Col md={12}>
<FormGroup>
<ControlLabel>Username</ControlLabel>
<input
ref={this.refName}
type="text"
placeholder="Name"
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={12}>
<Button bsStyle="primary" onClick={this.handleSubmit}>Submit</Button>
</Col>
</Row>
</div>
);
}}export default UncontrolledComponentForm;
When you don’t need to do instant validations or conditionally disable buttons or there are no dependent fields, you can use uncontrolled components. There is no need to make your components controlled if you don’t need the advantages it gives you. In my personal opinion, in the case of complex web apps, even if it is not needed, make your components controlled. So that whenever your requirement changes(like adding instant UI feedback), you can start making the required changes without having to first move the components from being uncontrolled to controlled.
Please feel free to comment and share your feedback.
Happy Coding!
Previous: React-Champ: Part I: Controlled vs Uncontrolled Components
Next in Series: TBD