# Работа с инпутами в React

Работа с инпутами в React происходит с помощью стейтов. Каждому инпуту назначается свой стейт, содержащий в себе `value` инпута.

Давайте посмотрим на примере. Пусть у нас есть инпут:

`function App() { return <div> <input /> </div>; }`

Пусть также у нас есть стейт:

`function App() { const [value, setValue] = useState('text'); return <div> <input /> </div>; }`

Давайте к атрибуту `value` инпута привяжем нас стейт:

`function App() { const [value, setValue] = useState('text'); return <div> <input value={value} /> </div>; }`

В таком случае получится, что при изменении стейта, реактивно поменяется и текст инпута.

Это, однако, дает интересный побочный эффект: теперь при запуске кода в браузере в инпуте невозможно поменять текст! Почему: потому что при вводе текста в инпут не меняется стейт `value`, соответственно, и текст в инпуте не должен меняться.

Попробуйте сами. Скопируйте мой код и запустите у себя. Попробуйте поизменять текст в инпуте - у вас ничего не получится. Откройте консоль браузера - вы увидите в ней предупреждение React. Это предупреждение указывает нам, что мы привязали стейт к инпуту, но тем самым заблокировали инпут.

Давайте сделаем так, чтобы в наш инпут можно было вводить текст. Для этого нужно сделать так, чтобы при вводе изменялся наш стейт на текущее значение инпута.

Для начала для этого нужно навесить на инпут событие `onChange`:

`function App() { const [value, setValue] = useState('text'); return <div> <input value={value} onChange={handleChange} /> </div>; }`

Данное событие в React ведет себя по-другому по сравнению с чистым JS. В React оно срабатывает сразу же по изменению инпута. То есть при вводе или удалении символа.

Давайте теперь добавим обработчик нашего события:

`function App() { const [value, setValue] = useState('text'); function handleChange() { } return <div> <input value={value} onChange={handleChange} /> </div>; }`

В этом обработчике мы должны прочитать текущий текст инпута и установить его в стейт с помощью функции `setValue`.

Проблема в том, что `this` данной функции не будет указывать на наш инпут - такова особенность React. Чтобы получить элемент, в котором случилось событие, нам необходимо использовать `event.target`:

`function App() { const [value, setValue] = useState('text'); function handleChange(event) { console.log(event.target); // ссылка на DOM элемент инпута } return <div> <input value={value} onChange={handleChange} /> </div>; }`

Выведем с помощью `event.target` текущий текст инпута:

`function App() { const [value, setValue] = useState('text'); function handleChange(event) { console.log(event.target.value); // текущий текст инпута } return <div> <input value={value} onChange={handleChange} /> </div>; }`

А теперь запишем текст инпута в наш стейт:

`function App() { const [value, setValue] = useState('text'); function handleChange(event) { setValue(event.target.value); } return <div> <input value={value} onChange={handleChange} /> </div>; }`

Теперь мы сможем вводить текст в инпут. При этом стейт `value` всегда будет содержать текущий текст инпута.

Мы можем легко убедится в этом. Выведем содержимое нашего текста в абзац. В этом случае при вводе текста в инпут введенный текст будет автоматически появляться в абзаце:

`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>; }`

Таким образом, для работы любого инпута нам нужно следующее: создать стейт для этого инпута, привязать стейт к атрибуту `value` инпута, навесить событие `onChange` на инпут, в обработчике события менять стейт инпута на его текст.

Данные операции нужно будет проводить с каждым инпутом. То есть, если у вас два инпута, то у вас будет два стейта и две функции-обработчика события `onChange`.

Сделайте два инпута. Пусть текст первого инпута выводится в первый абзац, а текст второго инпута - во второй абзац.

←→
↑