React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.
In this article, we’ll look at how to use uncontrolled components in React code.
Uncontrolled Components
Uncontrolled components are where we use the DOM properties to manipulate form inputs.
We can use a ref
to get form values directly from the DOM.
For example, we can write the following:
class App extends React.Component {
constructor(props) {
super(props);
this.input = React.createRef();
}
handleSubmit(event) {
alert(`Name submitted: ${this.input.current.value}`);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit.bind(this)}>
<label>
Name:
<input type="text" ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
In the code above we created the this.input
ref in the constructor and attached it to the input element.
Then when we type in something and click Submit, we get whatever we typed into the input box displayed in the alert box since we accessed it with this.input.current.value
.
This makes integrating React and non-React code easier since we’re using the DOM to get the value.
Default Values
The value
attribute on form elements will override the value in the DOM.
With an uncontrolled component, we often want to specify the initial value and leave subsequent updates uncontrolled.
We can set the defaultValue
attribute to do this:
class App extends React.Component {
constructor(props) {
super(props);
this.input = React.createRef();
}
handleSubmit(event) {
alert(`Name submitted: ${this.input.current.value}`);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit.bind(this)}>
<label>
Name:
<input type="text" defaultValue="Foo" ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
In the code above, we set the defaultValue
attribute to Foo
, which is the value of this.input.current.value
if we don’t change the input value.
The file input Tag
File inputs are always uncontrolled components because its value can only be set by a user and not programmatically.
Therefore, we have to use a ref to access its value.
For example, we can write the following:
class App extends React.Component {
constructor(props) {
super(props);
this.fileRef = React.createRef();
}
handleSubmit(event) {
alert(`Filename: ${this.fileRef.current.files[0].name}`);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit.bind(this)}>
<input type="file" ref={this.fileRef} />
<input type="submit" value="Submit" />
</form>
);
}
}
In the code above, we created a ref called fileRef
and attached it to the file input. Then we get the files[0].name
property that has the name of the selected file.
We can use the File API to do things with the selected file.
Conclusion
We can use uncontrolled components to get input values directly from the DOM.
This is useful for integrating React and non-React code. It’s also useful for quick and dirty apps.
We can set the default value of an uncontrolled input by setting the defaultValue
attribute with a value.
Also, file inputs are always uncontrolled. We use the File API to manipulate selected files from file inputs.