useUncontrolledState — это хук, предоставляемый
библиотекой React Aria, который упрощает работу с
компонентами, поддерживающими как контролируемое, так и неконтролируемое
состояние. Он позволяет компоненту корректно работать с внешним
управлением через пропсы, а при их отсутствии автоматически использовать
внутреннее состояние.
В React существует различие между контролируемыми и неконтролируемыми компонентами:
value и колбэк
onChange.useState.useUncontrolledState объединяет эти два подхода,
позволяя компоненту автоматически переключаться между ними без
дублирования кода.
Хук принимает объект с следующими ключами:
const [state, setState] = useUncontrolledState({
defaultValue: initialDefaultValue,
value: controlledValue,
onChange: handleChange,
});
Хук возвращает массив из двух элементов:
import { useUncontrolledState } from "@react-aria/utils";
import { useState } from "react";
function Counter() {
const [count, setCount] = useUncontrolledState({
defaultValue: 0
});
return (
{count}
);
}
В этом примере компонент сам управляет своим
состоянием. defaultValue задаёт начальное
значение.
function ControlledCounter({ value, onChange }) {
const [count, setCount] = useUncontrolledState({
value,
onChange
});
return (
{count}
);
}
Если передан проп value, хук не создаёт
внутреннего состояния и использует переданное значение. Любое
изменение через setCount вызывает onChange,
позволяя родителю контролировать состояние.
Синхронизация состояния
useUncontrolledState автоматически синхронизирует
внутреннее состояние с пропсами, если они меняются. Это особенно важно,
если родитель изменяет value динамически.
Обработка undefined Если value не
определён, хук гарантирует, что внутреннее состояние корректно
инициализируется defaultValue.
Идиоматический React Использование
useUncontrolledState позволяет писать чистые компоненты без
проверки контролируемости вручную через условные конструкции.
Поддержка любых типов данных Хук может работать
с числами, строками, булевыми значениями и объектами. Главное —
корректно использовать onChange для обновления
состояния.
Часто useUncontrolledState применяется в компонентах
типа:
Пример для Toggle:
function Toggle({ isSelected, onChange, defaultSelected }) {
const [selected, setSelected] = useUncontrolledState({
value: isSelected,
defaultValue: defaultSelected,
onChange
});
return (
);
}
Хук делает компонент универсальным: его можно использовать как
контролируемый через isSelected/onChange,
так и неконтролируемый через
defaultSelected.
defaultValue или аналог для
неконтролируемого режима. Это предотвращает ошибки с
undefined.onChange даже для неконтролируемых
компонентов, если нужно уведомление внешних слушателей.useUncontrolledState
для корректного разделения ответственности.setState, чтобы избежать проблем с мутированием
состояния:setState(prev => ({ ...prev, key: newValue }));
useUncontrolledState обеспечивает:
if (props.value !== undefined).