← Назад к вопросам

Как можно управлять input в React?

2.0 Middle🔥 211 комментариев
#React#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Управление input элементами в React

В React есть два основных подхода к управлению input элементами: контролируемые компоненты (controlled components) и неконтролируемые (uncontrolled components). Каждый имеет свои преимущества и применение.

1. Контролируемые компоненты (Controlled)

Это рекомендуемый подход в React. Значение input хранится в state, а React контролирует каждое обновление:

function LoginForm() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleEmailChange = (e) => {
    setEmail(e.target.value);
  };

  const handlePasswordChange = (e) => {
    setPassword(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Email:', email, 'Password:', password);
    // Отправка данных на сервер
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={handleEmailChange}
        placeholder="Enter email"
      />
      <input
        type="password"
        value={password}
        onChange={handlePasswordChange}
        placeholder="Enter password"
      />
      <button type="submit">Login</button>
    </form>
  );
}

2. Неконтролируемые компоненты (Uncontrolled)

Используйте ref для доступа к значению напрямую из DOM:

function FileUpload() {
  const fileInputRef = useRef(null);

  const handleSubmit = (e) => {
    e.preventDefault();
    const file = fileInputRef.current.files[0];
    console.log('Selected file:', file);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="file"
        ref={fileInputRef}
        defaultValue="initial"
      />
      <button type="submit">Upload</button>
    </form>
  );
}

3. Оптимизация с useCallback

Для больших форм можно оптимизировать производительность:

function OptimizedForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  });

  // useCallback предотвращает пересоздание функции при каждом рендере
  const handleChange = useCallback((e) => {
    const { name, value } = e.target;
    setFormData(prev => ({
      ...prev,
      [name]: value
    }));
  }, []);

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        name="name"
        value={formData.name}
        onChange={handleChange}
      />
      <input
        name="email"
        value={formData.email}
        onChange={handleChange}
      />
      <textarea
        name="message"
        value={formData.message}
        onChange={handleChange}
      />
      <button type="submit">Send</button>
    </form>
  );
}

4. Валидация в реальном времени

function FormWithValidation() {
  const [email, setEmail] = useState('');
  const [error, setError] = useState('');

  const handleChange = (e) => {
    const value = e.target.value;
    setEmail(value);

    // Валидация email
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(value) && value.length > 0) {
      setError('Invalid email format');
    } else {
      setError('');
    }
  };

  return (
    <div>
      <input
        type="email"
        value={email}
        onChange={handleChange}
      />
      {error && <span style={{ color: 'red' }}>{error}</span>}
    </div>
  );
}

5. Custom Hook для форм

Для переиспользуемой логики создайте hook:

function useForm(initialValues, onSubmit) {
  const [values, setValues] = useState(initialValues);
  const [errors, setErrors] = useState({});

  const handleChange = (e) => {
    const { name, value } = e.target;
    setValues(prev => ({
      ...prev,
      [name]: value
    }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    onSubmit(values);
  };

  return { values, errors, handleChange, handleSubmit };
}

// Использование
function MyForm() {
  const { values, handleChange, handleSubmit } = useForm(
    { name: '', email: '' },
    (data) => console.log(data)
  );

  return (
    <form onSubmit={handleSubmit}>
      <input name="name" value={values.name} onChange={handleChange} />
      <input name="email" value={values.email} onChange={handleChange} />
      <button type="submit">Submit</button>
    </form>
  );
}

Когда использовать какой подход?

Контролируемые компоненты:

  • Большинство случаев (рекомендуется)
  • Когда нужна валидация в реальном времени
  • Когда нужно программно менять значение
  • Когда нужно отслеживать каждое изменение

Неконтролируемые компоненты:

  • Интеграция с non-React кодом
  • Upload файлов (input type="file")
  • Когда нужны дефолтные значения
  • Простые формы без валидации

В современном React контролируемые компоненты - это стандартный подход, так как они дают полный контроль над состоянием формы.

Как можно управлять input в React? | PrepBro