useControlledState — это хук из библиотеки React
Aria, предназначенный для упрощения работы с компонентами,
которые могут быть как контролируемыми, так и неконтролируемыми. Он
обеспечивает единый способ управления состоянием, автоматически
подстраиваясь под сценарий использования.
В React различают контролируемые и неконтролируемые компоненты:
value,
onChange).useState.useControlledState объединяет эти два подхода, позволяя
компоненту корректно работать в любом сценарии.
import { useControlledState } from '@react-stately/utils';
function Example({ value, defaultValue, onChange }) {
const [state, setState] = useControlledState(value, defaultValue, onChange);
return (
<input
value={state}
onCha nge={e => setState(e.target.value)}
/>
);
}
Хук useControlledState принимает три параметра:
Этот подход гарантирует, что:
value, внутреннее состояние полностью
синхронизировано с пропсом и любое изменение инициируется через
onChange.value не передан, хук создает внутреннее состояние
и управляет им самостоятельно.useControlledState возвращает массив
[state, setState]:
onChange, если
неконтролируемый — обновляет внутреннее состояние напрямую.function ControlledInput({ value, onChange }) {
const [state, setState] = useControlledState(value, undefined, onChange);
return (
<input
value={state}
onCha nge={e => setState(e.target.value)}
/>
);
}
// Использование
<ControlledInput value={externalValue} onCha nge={handleChange} />
В этом примере состояние компонента полностью контролируется внешним
value. Любое изменение инициируется колбэком
onChange.
function UncontrolledInput({ defaultValue }) {
const [state, setState] = useControlledState(undefined, defaultValue);
return (
<input
value={state}
onCha nge={e => setState(e.target.value)}
/>
);
}
// Использование
<UncontrolledInput defaultValue="Hello" />
Здесь компонент использует внутреннее состояние, которое
инициализируется defaultValue.
useControlledState автоматически обновляет внутреннее
состояние при изменении value, если компонент
контролируемый.setState
всегда учитывает, контролируем компонент или нет, предотвращая
дублирование состояния.string, number), но и
объектом или массивом, при этом onChange будет получать
актуальное значение.function ControlledForm({ value, onChange }) {
const [formData, setFormData] = useControlledState(value, { name: '', age: '' }, onChange);
return (
<form>
<input
value={formData.name}
onCha nge={e => setFormData({ ...formData, name: e.target.value })}
/>
<input
value={formData.age}
onCha nge={e => setFormData({ ...formData, age: e.target.value })}
/>
</form>
);
}
Такой подход обеспечивает:
value и
defaultValue с различными начальными состояниями — это
может вызвать несогласованность.onChange корректно обновляет
внешнее состояние, если компонент контролируемый.useControlledState предпочтительно для
повторно используемых компонентов, чтобы избежать дублирования логики
состояния.useControlledState является фундаментальным инструментом
для создания гибких и универсальных компонентов в React
Aria, позволяя легко поддерживать оба сценария использования с
минимальными усилиями.