React-Champ: Part II: When and how to use uncontrolled components

Adarsh Singh
3 min readOct 14, 2018

--

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.

React Champ: Part II

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.

  1. Your form is very simple and doesn’t need any instant validation?
  2. Even if any validations are needed, they are done only when the form is submitted?
  3. 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');
}
}
Validating an uncontrolled input on “Submit”

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

--

--