8

Ошибка в ReactJS: Компонент изменяет неконтролируемый текстовый ввод на контролируемый

13

Описание проблемы:

При использовании моего компонента я столкнулся с предупреждением:

Warning: A component 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.

Проблема возникает при работе с текстовым полем input в методе render. Я использую состояние для управления значением поля, но в некоторых случаях значение this.state.fields["name"] может быть undefined, что приводит к тому, что React рассматривает это поле как неконтролируемое.

Вот мой код:

constructor(props) {
  super(props);
  this.state = {
    fields: {},
    errors: {}
  }
  this.onSubmit = this.onSubmit.bind(this);
}

onChange(field, e) {
  let fields = this.state.fields;
  fields[field] = e.target.value;
  this.setState({ fields });
}

render() {
  return(
    <div className="form-group">
      <input
        value={this.state.fields["name"]}
        onChange={this.onChange.bind(this, "name")}
        className="form-control"
        type="text"
        refs="name"
        placeholder="Name *"
      />
      <span style={{color: "red"}}>{this.state.errors["name"]}</span>
    </div>
  )
}

Как я могу исправить эту проблему, чтобы избежать предупреждения и гарантировать, что поле ввода всегда будет контролируемым?

5 ответ(ов)

0

Чтобы разместить текстовое поле внутри компонента, используйте следующий код:

<input
    className="class-name"
    type="text"
    id="id-123"
    value={this.state.value || ""}
    name="field-name"
    placeholder="Введите имя"
/>

Здесь мы добавили атрибуты, которые позволяют задавать класс, тип, идентификатор, значение, имя поля и текст подсказки для ввода. Не забудьте, что значение this.state.value должно быть предварительно определено в вашем состоянии компонента.

0

В дополнение к принятому ответу, если вы используете элемент input типа checkbox или radio, я обнаружил, что мне необходимо проверять атрибут checked на null или undefined.

<input
  id={myId}
  name={myName}
  type="checkbox" // или "radio"
  value={myStateValue || ''}
  checked={someBoolean ? someBoolean : false}
/>

Если вы используете TypeScript (или Babel), вы можете воспользоваться нулевым слиянием вместо логического оператора ИЛИ:

value={myStateValue ?? ''}
checked={someBoolean ?? false}

Таким образом, вы избежите потенциальных проблем с неопределёнными значениями.

0

Простыми словами, вы должны сначала задать начальное состояние.

Если вы не установите начальное состояние, React будет считать это неконтролируемым компонентом.

0

Это происходит потому, что значение не может быть undefined или null. Чтобы решить эту проблему, вы можете сделать так:

value={ this.state.value ?? "" }

Здесь используем оператор нулевого слияния (??), который вернёт пустую строку, если this.state.value равно undefined или null.

0

Ошибка возникает из-за того, что при использовании const [name, setName] = useState() вы инициализируете состояние name как undefined, что может вызвать проблему при попытке использовать это значение в текстовом поле.

Когда вы изменяете строку на const [name, setName] = useState(''), вы инициализируете состояние name как пустую строку. Это решает проблему, так как теперь name всегда будет строкой, и ваше текстовое поле сможет корректно обработать ввод.

Такой подход предпочтителен, когда вы хотите избежать ошибок, связанных с undefined, и гарантировать, что состояние всегда будет строкового типа.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь