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

Как можно контролировать input?

2.0 Middle🔥 231 комментариев
#React

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

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

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

Контроль элемента input в JavaScript

Контроль input элементов — это один из ключевых аспектов веб-разработки. Есть несколько подходов в зависимости от того, используем ли мы vanilla JavaScript, React, Vue или Angular.

Способы контроля input

1. Управляемые компоненты (Controlled Components) Состояние input полностью контролируется React компонентом через state.

2. Неуправляемые компоненты (Uncontrolled Components) Input сохраняет собственное состояние, доступ к значению через ref.

3. DOM API Прямое управление через JavaScript и DOM API.

4. Event Listeners Отслеживание событий input, change, blur и т.д.

5. Input validation Валидация в реальном времени с ограничениями.

Примеры кода

// СПОСОБ 1: React - Controlled Component
import { useState } from 'react';

function ControlledInput() {
  const [value, setValue] = useState('');
  const [errors, setErrors] = useState('');
  
  const handleChange = (e) => {
    const newValue = e.target.value;
    setValue(newValue);
    
    if (newValue.length < 3) {
      setErrors('Минимум 3 символа');
    } else {
      setErrors('');
    }
  };
  
  const handleFocus = (e) => {
    console.log('Input получил фокус');
  };
  
  const handleBlur = (e) => {
    console.log('Input потерял фокус, значение:', e.target.value);
  };
  
  return (
    <div>
      <input
        type="text"
        value={value}
        onChange={handleChange}
        onFocus={handleFocus}
        onBlur={handleBlur}
        placeholder="Введите текст"
        maxLength={50}
      />
      {errors && <span className="error">{errors}</span>}
      <p>Количество символов: {value.length}</p>
    </div>
  );
}

СПОСОБ 2: React - Uncontrolled с useRef

import { useRef } from 'react';

function UncontrolledInput() {
  const inputRef = useRef(null);
  
  const handleSubmit = () => {
    const value = inputRef.current.value;
    console.log('Значение:', value);
  };
  
  const clearInput = () => {
    inputRef.current.value = '';
    inputRef.current.focus();
  };
  
  return (
    <div>
      <input ref={inputRef} type="text" placeholder="Введите текст" />
      <button onClick={handleSubmit}>Отправить</button>
      <button onClick={clearInput}>Очистить</button>
    </div>
  );
}

СПОСОБ 3: Vue 3 - v-model

export default {
  data() {
    return {
      message: '',
      email: '',
      validationErrors: {}
    };
  },
  methods: {
    validateEmail() {
      const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!regex.test(this.email)) {
        this.validationErrors.email = 'Некорректный email';
      } else {
        this.validationErrors.email = null;
      }
    },
    handleInput(e) {
      if (this.message.length > 100) {
        this.message = this.message.substring(0, 100);
      }
    }
  },
  template: `
    <div>
      <input v-model="message" @input="handleInput" placeholder="Сообщение" />
      <p>Символов: {{ message.length }}/100</p>
      
      <input 
        v-model="email" 
        @blur="validateEmail" 
        type="email"
        placeholder="Email"
      />
      <span v-if="validationErrors.email" class="error">
        {{ validationErrors.email }}
      </span>
    </div>
  `
}

СПОСОБ 4: Vanilla JavaScript

const inputElement = document.getElementById('myInput');
const valueDisplay = document.getElementById('valueDisplay');

inputElement.addEventListener('input', (e) => {
  const value = e.target.value;
  valueDisplay.textContent = value;
  
  if (value.length < 3) {
    inputElement.classList.add('invalid');
  } else {
    inputElement.classList.remove('invalid');
  }
});

inputElement.addEventListener('focus', (e) => {
  console.log('Input в фокусе');
  inputElement.style.borderColor = 'blue';
});

inputElement.addEventListener('blur', (e) => {
  console.log('Input потерял фокус');
  inputElement.style.borderColor = '#ccc';
});

function setInputValue(newValue) {
  inputElement.value = newValue;
  inputElement.dispatchEvent(new Event('input', { bubbles: true }));
}

function getInputValue() {
  return inputElement.value;
}

СПОСОБ 5: Форма с валидацией

class FormController {
  constructor(formSelector) {
    this.form = document.querySelector(formSelector);
    this.inputs = this.form.querySelectorAll('input, textarea, select');
    this.errors = {};
    this.setupValidation();
  }
  
  setupValidation() {
    this.inputs.forEach(input => {
      input.addEventListener('blur', () => this.validateField(input));
      input.addEventListener('input', () => {
        delete this.errors[input.name];
      });
    });
  }
  
  validateField(input) {
    const value = input.value.trim();
    
    if (!value) {
      this.errors[input.name] = 'Поле обязательно';
      this.showError(input);
      return false;
    }
    
    if (input.type === 'email' && !this.isValidEmail(value)) {
      this.errors[input.name] = 'Некорректный email';
      this.showError(input);
      return false;
    }
    
    this.hideError(input);
    return true;
  }
  
  isValidEmail(email) {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
  }
  
  showError(input) {
    input.classList.add('error');
    let errorElement = input.parentElement.querySelector('.error-message');
    if (!errorElement) {
      errorElement = document.createElement('span');
      errorElement.className = 'error-message';
      input.parentElement.appendChild(errorElement);
    }
    errorElement.textContent = this.errors[input.name];
  }
  
  hideError(input) {
    input.classList.remove('error');
    const errorElement = input.parentElement.querySelector('.error-message');
    if (errorElement) {
      errorElement.remove();
    }
  }
  
  getFormData() {
    const data = {};
    this.inputs.forEach(input => {
      data[input.name] = input.value;
    });
    return data;
  }
}

const formController = new FormController('#myForm');

СПОСОБ 6: Input с маской

class InputMask {
  constructor(input, mask) {
    this.input = input;
    this.mask = mask;
    this.input.addEventListener('input', () => this.applyMask());
  }
  
  applyMask() {
    let value = this.input.value.replace(/\D/g, '');
    let formattedValue = '';
    let maskIndex = 0;
    
    for (let i = 0; i < this.mask.length && value.length > 0; i++) {
      if (this.mask[i] === '#') {
        formattedValue += value[maskIndex];
        maskIndex++;
      } else {
        formattedValue += this.mask[i];
      }
    }
    
    this.input.value = formattedValue;
  }
}

const phoneMask = new InputMask(
  document.getElementById('phone'),
  '+7 (###) ###-##-##'
);

Рекомендации

React: используй controlled components для большинства случаев, uncontrolled для интеграции с legacy кодом.

Vue: v-model — это наиболее идиоматичный способ, он упрощает двустороннюю привязку.

Vanilla JS: event listeners и DOM API дают полный контроль, но требуют больше кода.

Сложные формы: рассмотри React Hook Form или Formik для оптимизации производительности.

Заключение

Контроль input зависит от выбранного фреймворка. Вне зависимости от подхода, важно помнить о валидации, доступности и производительности. Для сложных форм лучше использовать проверенные библиотеки, которые оптимизируют re-renders и валидацию.

Как можно контролировать input? | PrepBro