У меня есть простой компонент реагирования с формой, которая, как мне кажется, имеет один контролируемый вход:
import React from 'react';
export default class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<form className="add-support-staff-form">
<input name="name" type="text" value={this.state.name} onChange={this.onFieldChange('name').bind(this)}/>
</form>
)
}
onFieldChange(fieldName) {
return function (event) {
this.setState({[fieldName]: event.target.value});
}
}
}
export default MyForm;
Когда я запускаю свое приложение, я получаю следующее предупреждение:
Предупреждение: MyForm изменяет неконтролируемый ввод текста типа для управления. Входные элементы не должны переключаться с неуправляемых на управляемые (или наоборот). Выберите между использованием контролируемого или неконтролируемого элемента ввода в течение срока службы компонента.
Я считаю, что мой вклад контролируется, поскольку он имеет ценность. Мне интересно, что я делаю не так?
Я использую React 15.1.0
источник
name={'question_groups.${questionItem.id}'}
?value
реквизит имеет ненулевое / неопределенное значение. Реквизит не должен соответствовать переменной состояния (это может быть просто константа, и компонент все равно будет считаться контролируемым). Ответ Адама более правильный и должен быть принят.Когда вы впервые визуализируете свой компонент,
this.state.name
он не установлен, поэтому он оценивается какundefined
илиnull
, и в итоге вы переходитеvalue={undefined}
илиvalue={null}
к своемуinput
.Когда ReactDOM проверяет, контролируется ли поле, он проверяет, если
value != null
(обратите внимание, что это!=
не так!==
), и, посколькуundefined == null
в JavaScript, он решает, что оно неконтролируемое.Таким образом, когда
onFieldChange()
вызывается,this.state.name
устанавливается строковое значение, ваш ввод переходит от неконтролируемого к контролю.Если вы сделаете это
this.state = {name: ''}
в своем конструкторе, потому что'' != null
ваш ввод будет иметь значение все время, и это сообщение исчезнет.источник
this.props.<whatever>
, что было проблемой с моей стороны. Спасибо, Адам!render()
, или выражение в самом теге - все, что вычисляетсяundefined
. Рад, что смог помочь!name
".undefined
передается изначально. Скорее, тот факт, чтоthis.state.name
в качестве переменной состояния не существует, делает ввод неконтролируемым. Например, наличиеthis.state = { name: undefined };
приведет к тому, что вход будет контролироваться. Следует понимать, что важно то, откуда взято значение, а не то, какое это значение.this.state = { name: undefined }
все равно приведет к неконтролируемому вводу.<input value={this.state.name} />
Desugars дляReact.createElement('input', {value: this.state.name})
. Поскольку доступ к несуществующему свойству объекта возвращаетundefined
, это приводит к точно такому жеReact.createElement('input', {value: undefined})
вызову функцииname
- не установлено или явно установлено значениеundefined
, поэтому React ведет себя таким же образом. Вы можете увидеть это поведение в этом JSFiddle.Другим подходом может быть установка значения по умолчанию внутри вашего ввода, например:
источник
Я знаю, что другие уже ответили на это. Но очень важный фактор, который может помочь другим людям, испытывающим подобные проблемы:
Вы должны
onChange
добавить обработчик в поле ввода (например, textField, флажок, радио и т. Д.). Всегда обрабатывайте активность черезonChange
обработчик.Пример:
Когда вы работаете с флажком, вам может потребоваться обработать его
checked
состояние с помощью!!
.Пример:
источник
Простое решение для решения этой проблемы - установить пустое значение по умолчанию:
источник
Один потенциальный недостаток при установке значения поля "" (пустая строка) в конструкторе - это если поле является необязательным и оставлено неотредактированным. Если вы не сделаете некоторый массаж перед отправкой формы, поле будет сохранено в вашем хранилище данных в виде пустой строки вместо NULL.
Эта альтернатива позволит избежать пустых строк:
источник
При использовании
onChange={this.onFieldChange('name').bind(this)}
в качестве входных данных вы должны объявить пустую строку вашего состояния в качестве значения поля свойства.неверный путь:
правильный путь:
источник
В моем случае мне не хватало чего-то действительно тривиального.
<input value={state.myObject.inputValue} />
Мое состояние было следующим, когда я получал предупреждение:
Чередуя мое состояние со ссылкой на ввод моей стоимости , моя проблема была решена:
источник
Если реквизиты вашего компонента были переданы как состояние, установите значение по умолчанию для ваших входных тегов.
источник
Установите значение для свойства name в исходном состоянии.
источник
Обновление для этого. Для использования React Hooks
const [name, setName] = useState(" ")
источник
" "
и нет""
? Это приводит к тому, что вы теряете любой текст подсказки, и если вы нажмете и введете текст, вы получите скрытый пробел перед вводом любых данных.Обычно это происходит только тогда, когда вы не контролируете значение поля, когда приложение запускается, и после того, как какое-то событие или какая-либо функция сработали или состояние изменилось, вы теперь пытаетесь контролировать значение в поле ввода.
Этот переход отсутствия контроля над входом и последующего контроля над ним и является причиной возникновения проблемы.
Лучший способ избежать этого - объявить некоторое значение для ввода в конструкторе компонента. Так что элемент input имеет значение с самого начала приложения.
источник
Для динамической установки свойств состояния для входов формы и их контроля вы можете сделать что-то вроде этого:
источник
Просто создайте запасной вариант для '', если this.state.name имеет значение null.
Это также работает с переменными useState.
источник