Value что значит в реакт
Перейти к содержимому

Value что значит в реакт

  • автор:

Формы — JS: React

Формы в HTML работают немного не так, как формы в React. Это связано с тем, что в HTML они имеют свое внутреннее состояние — место, в котором хранятся значения форм, тексты, выбранные опции и тому подобное.

 action=""> Name:  type="text" name="name" />   type="submit" value="Submit" />  

Форма выше при каждом изменении поля name изменяет свое внутреннее состояние, которое будет отправлено по нужному адресу при отправке.

В отличие от прямой работы с DOM (даже через jQuery), в React источником правды является состояние, а не DOM. Формы не являются исключением. Любое изменение в форме, посимвольно, если это ввод, должно быть перенесено в состояние. А элементы форм, чьи данные хранятся в состоянии React, называются управляемыми компонентами (controlled components).

В коде выше на каждое изменение в элементе input происходит извлечение содержимого через e.target.value и запись его в React. Последующая отправка не нуждается в самой форме, так как все данные уже есть в состоянии. Поэтому при отправке формы достаточно получить нужные данные из объекта-состояния и отправить их, например, на сервер. Обратите внимание: элемент формы становится управляемым (controlled components) только когда происходит подстановка его значения из React: /> .

Один из множества плюсов управляемых компонентов в том, что становится крайне легко проводить фильтрацию или валидацию. Например, если необходимо вводить данные в верхнем регистре (например, при вводе данных карты), то сделать это можно так:

handleChange = (e) =>  this.setState( value: e.target.value.toUpperCase() >); > 

В противовес управляемым компонентам, React позволяет использовать неуправляемые компоненты (uncontrolled components). При таком подходе состояние формы хранится в самом DOM. Этот способ нужен исключительно для интеграции со сторонними библиотеками или для работы с устаревшим («легаси») кодом. В нормальной ситуации он не понадобится.

Текстовая область

В HTML значение устанавливается как его содержимое:

 Like this 

В React для этого используется атрибут value :

Стоит отметить, что событие onChange в React работает так, как ожидается, в отличие от onChange в HTML, который срабатывает только когда элемент теряет фокус. Поэтому событие гарантированно происходит на каждое изменение. При этом данные из элемента формы извлекаются обычным способом через e.target.value . Ну а дальше все по старой схеме — данные обновляются в состоянии.

Выпадающий список

В HTML текущий элемент выбирается с помощью атрибута selected , проставленного на нужном option .

  value="">Select a fruit  value="grapefruit">Grapefruit  value="lime">Lime  selected value="coconut">Coconut  value="mango">Mango  

React предлагает другой, более простой и удобный способ. Достаточно проставить атрибут value компонента select в нужное значение.

Чекбокс и радиокнопка

Оба этих типа поддерживают атрибут checked . Если он выставлен, то элемент отмечается выбранным.

input name="isGoing" type="checkbox" checked=this.state.isGoing> onChange=this.handleChange> /> 

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Формы

Элементы формы HTML работают немного иначе, чем другие элементы DOM в React, потому что элементы формы по своей реализации сохраняют некоторое внутреннее состояние. Например, эта форма в обычном HTML принимает только имя:

form> label> Имя: input type="text" name="name" /> label> input type="submit" value="Отправить" /> form>

У этой формы есть поведение HTML-формы по умолчанию — переход на новую страницу при отправке пользователем формы. Если вы хотите такое поведение в React, это будет просто работать и так. Но в большинстве случаев удобно создать JavaScript-функцию, которая будет обрабатывать отправку формы и иметь доступ к данным, которые ввёл пользователь в форму. Общепринятый способ достичь этого — использование техники под названием «контролируемые компоненты».

В HTML элементы формы, такие как , и , обычно поддерживают собственное состояние и обновляют его в соответствии с пользовательскими входными данными. В React изменяемое состояние обычно хранится в свойстве state компонентов и обновляется только с помощью setState() .

Мы можем объединить всё это вместе, сделав состояние React «единственным источником данных (истины)». Затем компонент React, который отрисовывает форму, также контролирует, что происходит в этой форме при последующем вводе данных пользователем. Элемент поля ввода формы, значение которого контролируется React подобным образом, называется «контролируемым компонентом».

Например, если мы хотим, чтобы предыдущий пример выводил на консоль имя при отправке формы, мы можем написать её как контролируемый компонент:

class NameForm extends React.Component  constructor(props)  super(props); this.state = value: ''>;  this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); > handleChange(event)   this.setState(value: event.target.value>);  >  handleSubmit(event)  alert('Отправленное имя: ' + this.state.value); event.preventDefault(); > render()  return ( form onSubmit=this.handleSubmit>> label> Имя: input type="text" value=this.state.value> onChange=this.handleChange> />  label> input type="submit" value="Отправить" /> form> ); > >

Поскольку атрибут value установлен в нашем элементе формы, отображаемое значение всегда будет находится в this.state.value , что делает состояние React источником данных (истины). Поскольку handleChange выполняется при каждом нажатии клавиши, что приводит к обновлению состояния React, то отображаемое значение будет обновляться по мере ввода данных пользователем.

В контролируемом компоненте каждое изменение состояния будет связано с функцией-обработчиком. Это упрощает изменение или проверку входных данных пользователя. Например, если мы хотим, чтобы входные имена записывались заглавными буквами, мы могли бы написать handleChange таким образом:

handleChange(event)   this.setState(value: event.target.value.toUpperCase()>); >

В HTML элемент определяет свой текст по дочерним элементам:

textarea> Привет, это часть текста в многострочном текстовом поле textarea>

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

class EssayForm extends React.Component  constructor(props)  super(props); this.state =   value: 'Пожалуйста, напишите эссе о своём любимом DOM-элементе.'  >;  this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); > handleChange(event)   this.setState(value: event.target.value>);  >  handleSubmit(event)  alert('Отправленное эссе: ' + this.state.value); event.preventDefault(); > render()  return ( form onSubmit=this.handleSubmit>> label> Эссе: textarea value=this.state.value> onChange=this.handleChange> />  label> input type="submit" value="Отправить" /> form> ); > >

Обратите внимание, что this.state.value создаётся в конструкторе, так что текстовая область начинается с текста, определённого в нём.

В HTML создаёт выпадающий список. Например, этот HTML создаёт выпадающий список вкусов:

select> option value="grapefruit">Грейпфрутoption> option value="lime">Лаймoption> option selected value="coconut">Кокосoption> option value="mango">Мангоoption> select>

Обратите внимание, что изначально выбран пункт списка «Coconut» из-за атрибута selected . React вместо атрибута selected использует атрибут value в корневом теге select . Это удобнее в контролируемом компоненте, потому что нужно только обновить его в одном месте. Например:

class FlavorForm extends React.Component  constructor(props)  super(props); this.state = value: 'coconut'>;  this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); > handleChange(event)   this.setState(value: event.target.value>);  >  handleSubmit(event)  alert('Ваш любимый вкус: ' + this.state.value); event.preventDefault(); > render()  return ( form onSubmit=this.handleSubmit>> label> Выберите ваш любимый вкус: select value=this.state.value> onChange=this.handleChange>>  option value="grapefruit">Грейпфрутoption> option value="lime">Лаймoption> option value="coconut">Кокосoption> option value="mango">Мангоoption> select> label> input type="submit" value="Отправить" /> form> ); > >

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

Примечание

Вы можете передать массив в атрибут value , что позволяет вам выбрать несколько пунктов в теге select :

select multiple=true> value=['B', 'C']>>

Тег поля для загрузки файла

В HTML элемент позволяет пользователю выбрать один или несколько файлов из устройства хранения для загрузки на сервер или изменять его с помощью JavaScript через API File.

input type="file" />

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

Обработка нескольких полей ввода

Когда вам нужно обрабатывать несколько контролируемых элементов input , вы можете добавить атрибут name на каждый элемент и позволить функции-обработчику выбрать, что делать, исходя из значения event.target.name

class Reservation extends React.Component  constructor(props)  super(props); this.state =  isGoing: true, numberOfGuests: 2 >; this.handleInputChange = this.handleInputChange.bind(this); > handleInputChange(event)  const target = event.target; const value = target.type === 'checkbox' ? target.checked : target.value; const name = target.name;  this.setState(  [name]: value >); > render()  return ( form> label> Я собираюсь пойти: input name="isGoing"  type="checkbox" checked=this.state.isGoing> onChange=this.handleInputChange> /> label> br /> label> Количество гостей: input name="numberOfGuests"  type="number" value=this.state.numberOfGuests> onChange=this.handleInputChange> /> label> form> ); > >

Обратите внимание, что мы использовали синтаксис вычисляемого имени свойства из ES6 для обновления ключа состояния, соответствующему определённому имени поля ввода:

this.setState(  [name]: value >);

Это эквивалентно этому коду в ES5:

var partialState = >; partialState[name] = value; this.setState(partialState);

Кроме того, поскольку setState() автоматически объединяет частичное состояние в текущее состояние, нам нужно только вызвать его с изменёнными частями.

Значение null в контролируемом компоненте

Определение свойства value в контролируемом компоненте предотвращает пользователю изменять значение поля ввода, если вы этого не хотите. Если вы не указали value , но поле ввода всё ещё доступно для редактирования, возможно, вы случайно установили атрибуту value значение undefined или null .

Код ниже демонстрирует такой случай. (Сначала поле ввода заблокировано, но становится редактируемым после короткой задержки.)

ReactDOM.render(input value="hi" />, mountNode); setTimeout(function()  ReactDOM.render(input value=null> />, mountNode); >, 1000);

Альтернативы контролируемым компонентам

Иногда бывает сложно использовать контролируемые компоненты, потому что нужно писать обработчик событий для каждого способа, которым ваши данные могут измениться, и передать всё входное состояние через React-компонент. Это может стать особенно раздражающим, когда вы преобразуете ранее существовашую базу кода на React или интегрируете приложение React с библиотекой, отличной от React. В таких ситуациях вы можете рассмотреть использование неконтролируемых компонентов, альтернативный метод реализации форм с полями ввода.

Полноценные готовые решения

Если вы ищете готовое решение, включающее валидацию, отслеживание заполненных полей и обработку отправки формы, то Formik — один из популярных вариантов. Однако, этот инструмент создан с использованием тех же принципов контролируемых компонентов и управления состоянием, поэтому обязательно изучите их.

React. Работа с формами

Работа элементов HTML-форм в React немного отличается от работы других DOM-элементов, потому что элементы форм по своей природе обладают некоторым внутренним состоянием. К примеру, данная форма в нативном HTML принимает только имя:

form> label> Name: input type="text" name="name" /> /label> input type="submit" value="Submit" /> /form>

Эта форма имеет поведение HTML-формы по умолчанию: просмотр новой страницы, когда пользователь посылает форму. Если вам необходимо это поведение в React, оно работает как обычно. Но в большинстве случаев удобно иметь JavaScript-функцию, которая обрабатывает отправку формы и имеет доступ к данным, которые пользователь ввел в форму. Стандартным способом достижения этой цели является использование подхода «контролируемые компоненты».

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

В HTML-элементы форм, такие как , и как правило хранят свое собственное состояние и обновляют его на основании пользовательского ввода. В React модифицируемое состояние как правило является собственностью компонентов и обновляется только с помощью setState(). Мы можем скомбинировать эти обе особенности, делая состояние React “единственным источником достоверной информации (истины)”. В свою очередь React-компонент, который отрисовывает форму, также контролирует, что происходит на этой форме в ответ на последующий ввод пользователя. Элемент ввода формы (например, input), значение которого контролируется React, в этом случае называется «контролируемый компонент». В большинстве случаев рекомендуется использовать контролируемые компоненты для реализации форм. В контролируемом компоненте данные формы обрабатываются компонентом React.

Основы работы с формами

Пусть у нас в this.state.value хранится текст ‘hello’:

class App extends React.Component  constructor(props)  super(props); this.state =  value: 'hello' >; > >

Теперь в методе render сделаем инпут, и таже же сделаем так, чтобы в value инпута записалось значение из this.state.value:

class App extends React.Component  constructor(props)  super(props); this.state =  value: 'hello' >; > render()  return div> input value=this.state.value> /> /div>; > >

Запустите этот код — на экране вы увидите инпут с текстом ‘hello’. Однако, вас ждет сюрприз: вы не сможете поменять текст нашего инпута. Почему так? Потому что мы четко сказали, что в value инпута должно быть значение из this.state.value. Это значение не меняется — и значит value инпута тоже не будет меняться, даже если вы вручную что-то попытаетесь туда написать. Понятно, что такое поведение не очень удобно и нам нужно что-то с этим сделать. Что именно: нужно организовать двухстороннее связывание

  • this.state.value и value инпута должны зависеть друг от друга: при изменении одного должен меняться и другой. Первый шаг для этого следующий: нужно к нашему инпуту добавить событие onChange и привязать к нему какой-нибудь метод, назовем его, к примеру, handleChange.
class App extends React.Component  constructor()  super(); this.state =  value: 'hello' >; > //Срабатывает при любом изменении инпута: handleChange = () =>  //тут какой-то код > render()  return div> input value=this.state.value> onChange=this.handleChange> /> /div>; > >

Как работает событие onChange? — оно срабатывает при попытке любого изменения инпута. Например, если мы пытаемся ввести в него какой-то текст, то onChange будет срабатывать при каждом вводе символа. И, даже если текст инпута не будет меняться из-за привязанного this.state.value, событие onChange будет срабатывать и каждый раз вызывать метод handleChange. Чтобы содержимое инпута могло изменяться, для этого в методе handleChange нужно в свойство this.state.value записывать содержимое атрибута value нашего инпута.

Работа с textarea

Работа с текстареа осуществляется очень похожим на работу с инпутом образом — также добавляется атрибут value и событие onChange. Следующий код — выведет на экран textarea, в который можно будет вводить текст. Все изменения будут отображаться в абзаце над нашим textarea:

class App extends React.Component  constructor(props)  super(props); this.state =  value: 'hello' >; > //Записываем value текстареа в this.state.value: handleChange = (event) =>  this.setState( value: event.target.value >); > render()  return div> p>текст: this.state.value>/p> textarea value=this.state.value> onChange=this.handleChange> /> /div>; > >

Обратите внимание: React подход отличается подхода на чистом JavaScript. На чистом JS у текстареа нет атрибута value, кроме того, в чистом JS текстареа должен иметь закрывающий тег: , но в реакте мы пишем так: — подобно работе с инпутом.

Чекбоксы

Работа с чекбоксами также осуществляется по схожему принципу, только вместо атрибута value мы указываем атрибут checked. Если в этот атрибут передать true — то чекбокс будет отмечен, а если false — не будет отмечен:

return div> input type="checkbox" checked=тут должно быть true или false> /> /div>;

Конечно же, обычно в checked передается стейт, который может принимать только два значения: или true, или false. Так же, как и при работе с инпутами, если жестко задать значение атрибута checked — состояние чекбокса нельзя будет поменять. Для решения этой проблемы поступим так: будем по изменению чекбокса менять this.state.checked на противоположное ему значение, то есть на !this.state.checked.

class App extends React.Component  constructor(props)  super(props); this.state =  checked: true >; > //Меняем this.state.checked на противоположный: handleCheckboxChange = (event) =>  this.setState( checked: !this.state.checked >); > render()  return div> input type="checkbox" checked=this.state.checked> onChange=this.handleCheckboxChange> /> /div>; > >

Селекты

Давайте теперь займемся выпадающими списками select. Работа с ними также практически не отличается от работы с инпутами и чекбоксами.

class App extends React.Component  constructor(props)  super(props); this.state =  value: 'javascript' >; > //Изменяем this.state.value при изменении селекта: handleSelectChange = (event) =>  this.setState( value: event.target.value >); > render()  return div> p>Ваш выбор: this.state.value>/p> select value=this.state.value> onChange=this.handleSelectChange> > option>html/option> option>css/option> option>javascript/option> /select> /div>; > >

Изначально выбран будет пункт списка со значением ‘javascript’ и этот выбор будет отражаться в нашем абзаце. Но если выбор поменять — в абзаце он тоже поменяется. Давайте теперь тегам option дадим атрибут value, как это обычно и делается:

select> option value="0">Язык HTML/option> option value="1">Язык CSS/option> option value="2">Язык JavaScript/option> /select>

На самом деле без атрибута value, как это было сделано выше — плохо. Почему плохо: ведь текст option может меняться и это повлияет на работу нашего скрипта. К примеру, вместо текста ‘javascript’ мы сделаем текст ‘Язык JavaScript’ и теперь строчка this.state = просто не будет работать. А вот если мы привяжемся к value и напишем this.state =

  • все будет работать независимо от того, что написано в самом тексте тега option.
class App extends React.Component  constructor(props)  super(props); this.state = value: 0>; > //Изменяем this.state.value при изменении селекта: handleSelectChange = (event) =>  this.setState(value: event.target.value>); > render()  return div> p>Ваш выбор: this.state.value>/p> select value=this.state.value> onChange=this.handleSelectChange> > option value="0">Язык HTML/option> option value="1">Язык CSS/option> option value="2">Язык JavaScript/option> /select> /div>; > >

Итак, если вы запустите этот код, то увидите проблему — строка

Ваш выбор: будет выводить value нашего option, а никак не значение. Для того, чтобы поправить эту проблему, вначале сделаем следующее: не будем создавать теги option вручную, а сделаем массив this.state.langs и из этого массива и сформируем наш селект, у нас по-прежнему есть строка this.state.value, которая выводит value option, а не его значение:

p>Ваш выбор: this.state.value>/p>

Давайте поправим ее так, чтобы она подтягивала значение из массива this.state.langs по его ключу this.state.value:

p>Ваш выбор: this.state.langs[this.state.value]>/p>

Радиокнопки

Работа с radio несколько отличается, к примеру, от тех же чекбоксов. Проблема в том, что у нескольких радио будет один и тот же стейт, но разные value. Поэтому работа происходит следующем образом: в атрибут value записывают значение радио, а в атрибут checked — специальное условие, которое проверяет, равен ли this.state.option определенному значению. Если равен — радиокнопка станет отмеченной, а если не равен — будет не отмеченной. Пример: пусть this.state.option — это стейт, в котором будет хранится значение радио. Сделаем 2 радиокнопки и дадим одной value=“option1”, а второй — value=“option2”. Тогда для проверки того, будет ли первая радиокнопка отмечена, ей в атрибут checked запишем следующее: checked=. Получится, что если в this.state.option лежит option1 первая радиокнопка будет отмеченной, а если не лежит — то не будет. Аналогичную строку запишем и для второй радиокнопки — checked=, только здесь мы сравниванием this.state.option уже с option2. Для каждой радио также напишем атрибут onChange и прикрепим к нему метод handleRadioChange. Ну, здесь все как обычно — так же, как для инпутов и чекбоксов. Давайте соберем все вместе и запустим:

class App extends React.Component  constructor(props)  super(props); this.state = option: 'option1'>; > //Изменяет this.state.option при изменении радио: handleRadioChange = (event) =>  this.setState(option: event.target.value>); > render()  return div> p>Ваш выбор: this.state.option>/p> input name="lang" type="radio" value="option1" checked=this.state.option == 'option1'> onChange=this.handleRadioChange> /> input name="lang" type="radio" value="option2" checked=this.state.option == 'option2'> onChange=this.handleRadioChange> /> /div>; > >

Значение по умолчанию

Иногда бывает следующая ситуация: вы хотите сделать так, чтобы по умолчанию в инпуте уже было какое-то значение. При этом вы хотите, чтобы из стейта было взято только начальное значение инпута, а сам инпут не был бы привязан к этому стейту. Способ сделать это есть: нужно воспользоваться атрибутом defaultValue:

class App extends React.Component  constructor(props)  super(props); this.state = value: 'hello'>; > render()  return( div> input defaultValue=this.state.value> /> /div> ); > >

Запустите этот код — и вы увидите на экране инпут со значением ‘hello’. Но это значение можно будет сменить, при этом this.state.value не поменяется — двухсторонней связи нет.

Для чекбоксов существует аналогичный атрибут defaultChecked, с помощью которого можно задать начальное состояние (отмечен или нет):

class App extends React.Component  constructor(props)  super(props); this.state = checked: true>; > render()  return div> input type="checkbox" defaultChecked=this.state.checked> /> /div>; > >

Written by Vadim Goloviychuk

Как правильно взять value от input-а и передать в React

есть текстовой input и button, при нажатии на button, value от inputa должен передаться компонент. Сейчас при каждом изменении value сохраняется в state, а при нажатии уже передается. Правильно ли так ? Получается что, при каждом изменении value вызывается callback onChange, а тот вызывает setState.

Отслеживать
задан 24 ноя 2018 в 12:56
Albert Petrosyan Albert Petrosyan
21 1 1 серебряный знак 2 2 бронзовых знака

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Привел пример с обоими вариантами. Можете оценить преимущества обоих.

Чтобы не писать в state, вы можете получить значение input по его ref в момент нажатия кнопки

class App extends React.Component < constructor(props) < super(props); this.state = < value: '', valueOld: '', changed: false, length: 0 >> input1Change = (e) => < let next = this.state; next.value = e.target.value; next.changed = next.value !== next.valueOld; next.length = e.target.value.length; this.setState(next); >button1Click = () => < alert(`Кнопка1: Введен текст $`); > button2Click = () => < let text = this.input2.value; if(text && text.length >0) < alert(`Кнопка2: Введен текст $`); > else < alert(`Кнопка2: Ничего не введено`); >> render() < return ( 
Пример со state
this.input1 = ref> onChange= value= />
Текст изменен, введено символов

>
Пример без state
this.input2 = ref> />
); > > ReactDOM.render(, document.getElementById('root'));

Отслеживать
ответ дан 24 ноя 2018 в 15:37
Dmitry Kozlov Dmitry Kozlov
6,688 2 2 золотых знака 15 15 серебряных знаков 30 30 бронзовых знаков

Все зависит от вашей архитектуры и принципов по которым вы строите свое приложение. Если брать к примеру подход Flux, к архитектуре от facebook https://habr.com/ru/post/246959/ , то основной принцип в вашем случае будет говорить, о том, что компонент должен не чего не знать о стейте, быть чистой функцией и выполнять только то, что приходит по пропсам. Отсюда вывод, что согласно этого подхода к архитектуре, ваш компонент должен отправить данные в стейт и ждать от него команды. Если есть еще и сервер, то отправляем на сервер (но не из компонента), сервер дает добро, связывается с стейтом, стейт присылает новые пропсы

Отслеживать
ответ дан 27 фев 2021 в 18:09
101 3 3 бронзовых знака

  • javascript
  • reactjs
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

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

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *