How to Update Uncontrolled Components in React
Uncontrolled components in React rely on the DOM to store and manage
their state, rather than using React’s internal state. While they are
typically designed to be self-managing, you can update them
programmatically when necessary. This article covers the primary methods
for updating uncontrolled components in React, including using React
refs to manipulate the DOM directly, leveraging the key
prop for force-resetting, and managing initial values with default
properties.
1. Updating Values Programmatically Using Refs
The most common way to update an uncontrolled component is by using a
React ref. By attaching a ref to the form element, you gain
direct access to the underlying DOM node, allowing you to modify its
value directly.
import { useRef } from 'react';
function UncontrolledInput() {
const inputRef = useRef(null);
const updateValue = () => {
// Directly updating the DOM node's value
if (inputRef.current) {
inputRef.current.value = 'New Updated Value';
}
};
return (
<div>
<input ref={inputRef} type="text" defaultValue="Initial Value" />
<button onClick={updateValue}>Update Input</button>
</div>
);
}In this example, clicking the button directly alters the
value property of the HTML input element without triggering
a React state re-render.
2. Resetting the
Component Using the key Prop
If you need to completely reset or update an uncontrolled component
to a new default value from a parent component, you can use the
key prop. Changing the key forces React to
unmount the old component and mount a brand-new instance,
re-initializing it with the new defaultValue.
import { useState } from 'react';
function ParentComponent() {
const [resetId, setResetId] = useState(0);
const handleReset = () => {
setResetId(prevId => prevId + 1);
};
return (
<div>
{/* Changing the key forces the input to remount with the defaultValue */}
<input key={resetId} type="text" defaultValue="Fresh Start Value" />
<button onClick={handleReset}>Reset Input Field</button>
</div>
);
}This technique is highly effective when you need to clear forms or sync an uncontrolled element with new data fetched from an external source.
3. Setting Initial
Updates with defaultValue
When working with uncontrolled components, you should avoid using the
value attribute, as doing so turns the component into a
controlled one. Instead, use defaultValue (or
defaultChecked for checkboxes and radio buttons). This sets
the initial value but leaves the DOM in control of subsequent
updates.
function DefaultValueExample() {
return (
<input
type="text"
defaultValue="This is the initial, editable value"
/>
);
}If the defaultValue prop changes after the initial
mount, React will not update the value in the DOM. To handle subsequent
updates, you must pair this approach with the key prop
method described above.