Поле не реагує на введення. Причина - value без onChange:
<input value={title} /> // поле лише для читання
Контрольоване поле завжди показує те, що передано у value. Користувач натискає клавішу, браузер змінює поле, React повертає старе значення. У консолі - попередження: «You provided a value prop to a form field without an onChange handler».
Варіанти виправлення:
- потрібне лише початкове значення -
defaultValue={title}; - поле має керуватися станом - додати
onChange={(e) => setTitle(e.target.value)}; - поле справді лише для читання - явно
readOnly.
Курсор стрибає в кінець чи на початок. Типові причини:
1. Асинхронне оновлення стану:
onChange={async (e) => {
await validate(e.target.value);
setTitle(e.target.value); // запізно - поле вже перемальовано зі старим значенням
}}
Стан контрольованого поля треба оновлювати синхронно в обробнику, а асинхронну перевірку робити окремо.
2. Поле перестворюється на кожен рендер:
- компонент поля оголошено всередині іншого компонента - на кожен рендер це новий тип компонента, React знищує старий
<input>і створює новий; - змінюється
keyполя (наприклад,key={Math.random()}).
function Form() {
// помилка: новий компонент на кожен рендер
const Field = (props) => <input {...props} />;
return <Field value={title} onChange={...} />;
}
Компоненти оголошують на верхньому рівні модуля.
3. Перетворення значення на ходу (setTitle(e.target.value.toUpperCase())) іноді збиває позицію курсора в деяких браузерах. Для форматування (телефон, сума) краще форматувати при виході з поля чи спеціальні бібліотеки масок.
value={null} чи undefined робить поле неконтрольованим - а коли значення з'явиться, React попередить про перемикання режиму. Початкове значення - ''.