React - Изменение неконтролируемого ввода
У меня есть простой компонент React с формой, который, как мне кажется, содержит одно контролируемое поле ввод. Вот код:
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;
Когда я запускаю своё приложение, я получаю следующее предупреждение:
Warning: MyForm is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.
Я считаю, что моё поле ввода контролируемое, поскольку у него есть значение. Я не понимаю, что именно я делаю неправильно.
Я использую React версии 15.1.0.
5 ответ(ов)
Другой подход - это установить значение по умолчанию внутри вашего поля ввода, например, так:
<input name="name" type="text" value={this.state.name || ''} onChange={this.onFieldChange('name').bind(this)}/>
В этом примере мы используем this.state.name
для установки значения. Если this.state.name
является undefined
или null
, будет использоваться пустая строка. Это позволяет избежать проблем с управляемыми компонентами в React.
Я знаю, что другие уже на это отвечали. Но очень важный момент, который может помочь другим людям, сталкивающимся с подобными проблемами:
Вы должны добавить обработчик onChange
в ваше поле ввода (например, textField, checkbox, radio и т.д.). Всегда обрабатывайте действия через обработчик onChange
.
Пример:
<input ... onChange={this.myChangeHandler} ... />
Когда вы работаете с чекбоксом, возможно, вам понадобится обрабатывать его состояние checked
с помощью !!
.
Пример:
<input type="checkbox" checked={!!this.state.someValue} onChange={.....} >
Ссылка: https://github.com/facebook/react/issues/6779#issuecomment-326314716
Простой способ решения этой проблемы — установить значение по умолчанию пустым:
<input name='myInput' value={this.state.myInput || ''} onChange={this.handleChange} />
Таким образом, если this.state.myInput
содержит значение null
, undefined
или любое другое ложное значение, то в качестве значения будет использовано пустая строка. Это поможет избежать ошибок, связанных с неинициализированным состоянием поля ввода.
У меня была такая же проблема. Проблема заключалась в том, что я оставлял состояние пустым:
const [name, setName] = useState()
Я исправил это, добавив пустую строку следующим образом:
const [name, setName] = useState('')
Теперь все работает как задумано!
Одним из возможных недостатков установки значения поля в конструкторе как "" (пустая строка) является то, что если это поле является опциональным и не редактируется, то, если вы не проведете предварительную обработку перед отправкой формы, поле будет сохранено в вашем хранилище данных как пустая строка вместо NULL.
Чтобы избежать хранения пустых строк, вы можете использовать следующий подход:
constructor(props) {
super(props);
this.state = {
name: null
}
}
...
<input name="name" type="text" value={this.state.name || ''}/>
В этом примере, если значение name
в состоянии равно null
, то поле ввода будет отображать пустую строку, но в хранилище данных будет сохранено значение null
, что может быть более предпочтительным для работы с опциональными полями.
Обнаружена ошибка: Невозможное нарушение: Неверный тип элемента: ожидался строковый тип (для встроенных компонентов) или класс/функция, но получен объект
Что делает npm install --legacy-peer-deps? Когда рекомендуется использовать и какой потенциальный случай?
Как получить полный объект в console.log() Node.js, а не '[Object]'?
Как реализовать дебаунс?
Добавление тега script в React/JSX