Работа с inputs в React
Работата с inputs в React става с помощта на
състояния. На всеки input се задава свое
състояние, съдържащо неговата value стойност.
Нека разгледаме пример. Да предположим, че имаме input:
function App() {
return <div>
<input />
</div>;
}
Да предположим също, че имаме състояние:
function App() {
const [value, setValue] = useState('text');
return <div>
<input />
</div>;
}
Нека свържем нашето състояние с атрибута
value на input:
function App() {
const [value, setValue] = useState('text');
return <div>
<input value={value} />
</div>;
}
В този случай ще се получи, че при промяна на състоянието, реактивно ще се промени и текстът на input.
Това обаче дава интересен страничен ефект:
сега при стартиране на кода в браузъра в input
е невъзможно да се промени текстът! Защо: защото
при въвеждане на текст в input не се променя
състоянието value, съответно, и текстът
в input не трябва да се променя.
Опитайте сами. Копирайте моя код и го пуснете при вас. Опитайте да променяте текста в input - няма да успеете. Отворете конзолата на браузъра - ще видите в нея предупреждение от React. Това предупреждение ни посочва, че сме свързали състояние с input, но по този начин сме го блокирали.
Нека направим така, че в нашия input да може да се въвежда текст. За целта трябва да се направи така, че при въвеждане да се променя нашето състояние на текущата стойност на input.
Първо, за целта трябва да се добави към input
събитието onChange:
function App() {
const [value, setValue] = useState('text');
return <div>
<input value={value} onChange={handleChange} />
</div>;
}
Това събитие в React се държи различно в сравнение с чист JS. В React то се задейства веднага при промяна на input. Тоест при въвеждане или изтриване на символ.
Нека сега добавим обработваща функция на нашето събитие:
function App() {
const [value, setValue] = useState('text');
function handleChange() {
}
return <div>
<input value={value} onChange={handleChange} />
</div>;
}
В тази обработваща функция трябва да прочетем текущия
текст на input и да го зададем в състоянието с помощта
на функцията setValue.
Проблемът е, че this на тази функция
няма да сочи към нашия input - това е
особеност на React. За да получим елемента,
в който се е случило събитието, е необходимо
да използваме event.target:
function App() {
const [value, setValue] = useState('text');
function handleChange(event) {
console.log(event.target); // препратка към DOM елемента на input
}
return <div>
<input value={value} onChange={handleChange} />
</div>;
}
Нека изведем с помощта на event.target текущия
текст на input:
function App() {
const [value, setValue] = useState('text');
function handleChange(event) {
console.log(event.target.value); // текущият текст на input
}
return <div>
<input value={value} onChange={handleChange} />
</div>;
}
А сега нека запишем текста на input в нашето състояние:
function App() {
const [value, setValue] = useState('text');
function handleChange(event) {
setValue(event.target.value);
}
return <div>
<input value={value} onChange={handleChange} />
</div>;
}
Сега вече можем да въвеждаме текст в input. При
това състоянието value винаги ще съдържа
текущия текст на input.
Можем лесно да се убедим в това. Нека изведем съдържанието на нашия текст в параграф. В този случай при въвеждане на текст в input, въведеният текст ще се появява автоматично в параграфа:
function App() {
const [value, setValue] = useState('');
function handleChange(event) {
setValue(event.target.value);
}
return <div>
<input value={value} onChange={handleChange} />
<p>text: {value}</p>
</div>;
}
Можем да пренапишем на по-компактен вариант с анонимна стрелкова функция:
function App() {
const [value, setValue] = useState('');
return <div>
<input value={value} onChange={event => setValue(event.target.value)} />
<p>text: {value}</p>
</div>;
}
По този начин, за работа на който и да е input
ни е нужно следното: да създадем състояние за този
input, да свържем състоянието с атрибута value
на input, да добавим събитието onChange към input,
в обработващата функция на събитието да променяме състоянието на input
на неговия текст.
Тези операции ще трябва да се извършват с всеки
input. Тоест, ако имате два inputs,
тогава ще имате две състояния и две функции-обработвачи
на събитието onChange.
Направете два inputs. Нека текстът на първия input се извежда в първия параграф, а текстът на втория input - във втория параграф.