Управляемые и неуправляемые компоненты

В библиотеке Chakra UI компоненты можно использовать как управляемые (controlled), так и неуправляемые (uncontrolled). Понимание различий между этими подходами критически важно для построения интерфейсов, где требуется гибкость в управлении состоянием и реактивность компонентов.


Неуправляемые компоненты

Неуправляемые компоненты сами контролируют своё внутреннее состояние. Это означает, что значение поля ввода или состояния компонента хранится внутри самого компонента, и разработчик не обязан напрямую следить за этим состоянием. Такой подход часто удобен для простых форм или компонентов с локальной логикой.

Пример: Input

import { Input } from "@chakra-ui/react";

function UncontrolledInput() {
  return <Input placeholder="Введите текст" />;
}

Здесь <Input /> хранит своё значение самостоятельно. Можно получить текущее значение через ref, но это не обязательно для базового использования.

Особенности неуправляемых компонентов:

  • Простая интеграция, минимальный код для базовых случаев.
  • Значение не синхронизируется напрямую с состоянием React.
  • Для доступа к значению используется ref или событие onChange при необходимости.
import { useRef } from "react";
import { Input, Button } from "@chakra-ui/react";

function UncontrolledForm() {
  const inputRef = useRef();

  const handleSubmit = () => {
    alert(`Введено: ${inputRef.current.value}`);
  };

  return (
    <>
      <Input ref={inputRef} placeholder="Введите текст" />
      <Button onCl ick={handleSubmit}>Отправить</Button>
    </>
  );
}

Управляемые компоненты

Управляемые компоненты полностью контролируются состоянием React. Все изменения значения происходят через пропсы и обработчики событий. Такой подход позволяет синхронизировать состояние компонентов с другими частями приложения и реализовывать сложные логики валидации или реакции на изменения.

Пример: Input с управлением

import { useState } from "react";
import { Input } from "@chakra-ui/react";

function ControlledInput() {
  const [value, setValue] = useState("");

  const handleChange = (event) => {
    setValue(event.target.value);
  };

  return <Input value={value} onCha nge={handleChange} placeholder="Введите текст" />;
}

Особенности управляемых компонентов:

  • Значение полностью синхронизировано со состоянием React.
  • Позволяет реализовать сложные зависимости и динамическую валидацию.
  • Упрощает интеграцию с формами, библиотеками валидации и стором состояния.

Применение в Chakra UI

Большинство компонентов Chakra UI поддерживают оба подхода. Ключевые моменты для использования:

  1. Input, Textarea, Select

    • Управляемый: передаётся value и onChange.
    • Неуправляемый: используется только defaultValue или ref.
  2. Checkbox и Radio

    • Управляемый: isChecked + onChange.
    • Неуправляемый: defaultIsChecked.
import { Checkbox } from "@chakra-ui/react";
import { useState } from "react";

function CheckboxExample() {
  const [checked, setChecked] = useState(false);

  return (
    <Checkbox isChecked={checked} onCha nge={(e) => setChecked(e.target.checked)}>
      Согласен с условиями
    </Checkbox>
  );
}
  1. Switch и Slider

    • Имеют аналогичную логику: управляемый вариант через isChecked/value, неуправляемый через defaultIsChecked/defaultValue.

Преимущества и ограничения

Тип компонента Преимущества Ограничения
Неуправляемый (uncontrolled) Легкая интеграция, меньше кода, быстрый старт Сложнее синхронизировать с глобальным состоянием
Управляемый (controlled) Полная синхронизация, легко реализовать логику и валидацию Требует больше кода, состояние должно быть определено заранее

Рекомендации по выбору подхода

  • Неуправляемые компоненты подходят для простых форм или компонентов с локальным использованием, где нет необходимости отслеживать состояние глобально.
  • Управляемые компоненты эффективны для динамических интерфейсов, форм с валидацией, интеграции с Redux, Zustand или другими глобальными состояниями.
  • В сложных проектах часто используется смешанный подход: базовые поля остаются неуправляемыми, а ключевые элементы формы управляются через состояние React для большей предсказуемости.

Интеграция с формами

Chakra UI легко интегрируется с библиотеками форм, такими как React Hook Form или Formik. Управляемые компоненты лучше подходят для этих библиотек, так как они ожидают контроль состояния через пропсы.

Пример с React Hook Form:

import { useForm } from "react-hook-form";
import { Input, Button } from "@chakra-ui/react";

function FormWithHook() {
  const { register, handleSubmit } = useForm();

  const onSub mit = (data) => {
    console.log(data);
  };

  return (
    <form onSub mit={handleSubmit(onSubmit)}>
      <Input {...register("username")} placeholder="Имя пользователя" />
      <Button type="submit">Отправить</Button>
    </form>
  );
}

Здесь <Input /> управляется библиотекой, и его состояние синхронизировано через React Hook Form.


Итоговая структура использования

  1. Определить, нужно ли полностью контролировать компонент или достаточно локального состояния.
  2. Выбирать defaultValue/defaultIsChecked для неуправляемых компонентов.
  3. Использовать value/isChecked + onChange для управляемых компонентов.
  4. Интегрировать с формами и глобальными состояниями через управляемые компоненты.

Этот подход обеспечивает гибкость интерфейсов в Chakra UI и позволяет масштабировать проекты, поддерживая чистую архитектуру компонентов.