Предупреждение: компонент изменяет неконтролируемый ввод текста типа, которым нужно управлять. Элементы ввода не должны переключаться с неконтролируемого на управляемый (или наоборот). Выберите между использованием контролируемого или неконтролируемого элемента ввода на протяжении всего срока службы компонента. *

Вот мой код:

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(
    
{this.state.errors["name"]}
) }

Riya Kapuria

Ответов: 19

Ответы (19)

Причина в том, что в состоянии, которое вы определили:

this.state = { fields: {} }

поля как пустой объект, поэтому при первом рендеринге this.state.fields.name будет undefined, а поле ввода получит свое значение как:

value={undefined}

Из-за этого поле ввода станет неконтролируемым.

После того, как вы введете любое значение в поле ввода, поля в состоянии изменится на:

this.state = { fields: {name: 'xyz'} }

И тогда поле ввода преобразуется в управляемый компонент; поэтому вы получаете сообщение об ошибке:

Компонент изменяет неконтролируемый ввод текста типа на контролируемый.

Возможные решения:

1- Определите поля в состоянии как:

this.state = { fields: {name: ''} }

2- Или определите свойство значения, используя Оценка короткого замыкания, например:

value={this.state.fields.name || ''}   // (undefined || '') = ''

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

<ввод
  id = {myId}
  name = {myName}
  type = "checkbox" // или "радио"
  значение = {myStateValue || ''}
  checked = {someBoolean? someBoolean: false}
  />

И если вы используете TS (или Babel), вы можете использовать объединение с нулевым значением вместо логического оператора OR:

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

Если вы используете множественный ввод в поле, выполните следующие действия: Например:

class AddUser расширяет React.Component {
   конструктор (реквизит) {
     супер (реквизит);

     this.state = {
       поля: {Имя пользователя: '', Пароль: ''}
     };
   }

   onChangeField = event => {
    пусть name = event.target.name;
    пусть значение = event.target.value;
    this.setState (prevState => {
        prevState.fields [имя] = значение;
        возвращение {
           поля: prevState.fields
        };
    });
  };

  оказывать() {
     const {Имя пользователя, Пароль} = this.state.fields;
     возвращение (
         <форма>
             
); } }

Найдите свою проблему по адресу:

onChangeField = event => {
    пусть name = event.target.name;
    пусть значение = event.target.value;
    this.setState (prevState => {
        prevState.fields [имя] = значение;
        возвращение {
            поля: prevState.fields
        };
    });
};

Предупреждение: компонент изменяет неконтролируемый ввод текста типа, которым нужно управлять. Элементы ввода не должны переключаться с неконтролируемого на управляемый (или наоборот). Выберите между использованием контролируемого или неконтролируемого элемента ввода на протяжении всего срока службы компонента.

Решение: проверьте, не является ли значение неопределенным

React / Formik / Bootstrap / TypeScript

пример:

{ values?.purchaseObligation.remainingYear ?
   : null
}

Может применяться множественный подход:

  • Подход на основе классов: используйте локальное состояние и определите существующее поле со значением по умолчанию:
constructor(props) {
    super(props);
    this.state = {
      value:''
    }
  }


  • Использование Hooks React> 16.8 в компонентах функционального стиля:
[value, setValue] = useState('');


  • При использовании propTypes и предоставлении значения по умолчанию для propTypes в случае компонента HOC в функциональном стиле.
 HOC.propTypes = {
    value       : PropTypes.string
  }
  HOC.efaultProps = {
    value: ''
  }

function HOC (){

  return ()

}


Лучший способ исправить это - установить начальное состояние на ''.

конструктор (реквизит) {
 супер (реквизит)
  this.state = {
    fields: {
      имя: ''
    }
  }
  this.onChange = this.onChange.bind (это);
}

onChange (e) {
  this.setState ({
    fields: {
     ... this.state.fields,
     [e.target.name]: e.target.value
    }
  })
}


оказывать() {
  возвращение(
    
<ввод значение = {this.state.fields.first_name} onChange = {this.onChange} className = "контроль формы" name = "first_name" // То же, что и ключ состояния type = "текст" refs = "имя" placeholder = "Имя *" /> {this.state.errors.first_name}
) }

Тогда вы все равно можете запускать свои проверки, такие как if (field), и по-прежнему получать тот же результат, если у вас есть значение как ''.

Теперь, поскольку ваше значение теперь классифицируется как тип строка вместо undefined после оценки. Таким образом, очистив ошибку из консоли большого красного блока 😁😎.

Как упоминалось выше, вам нужно установить начальное состояние, в моем случае я забыл добавить кавычки '' внутри setSate ();

  const AddUser = (props) => {
  const [enteredUsername, setEnteredUsername] = useState()
  const [enteredAge, setEnteredAge] = useState()

Выдает следующую ошибку

enter image description here

Правильный код - просто установить начальное состояние на пустую строку ''

  const AddUser = (props) => {
  const [enteredUsername, setEnteredUsername] = useState('')
  const [enteredAge, setEnteredAge] = useState('')

Изменение значения на defaultValue разрешит это.

Примечание:

defaultValue только для начальной загрузки. Если вы хотите инициализировать input, тогда вы должны использовать defaultValue, но если вы хотите использовать state, чтобы изменить значение, вам нужно использовать значение. Прочтите здесь, чтобы узнать больше.

Я использовал value = {this.state.input || ""} in input, чтобы избавиться от этого предупреждения.

ПРОСТО, сначала нужно установить начальное состояние

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

Используя React Hooks, также не забудьте установить начальное значение.
Я использовал , а начальное eventStart было как

const [eventStart, setEventStart] = useState ();
вместо
const [eventStart, setEventStart] = useState ('');.

Разница в пустой строке в скобках.
Кроме того, если вы сбрасываете форму после отправки, как я, снова вам нужно установить ее на пустую строку, а не только на пустые круглые скобки.

Это всего лишь мой небольшой вклад в эту тему, может кому поможет.

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

Например, если у вас это состояние:

state = {
    "a" : "A",
    "b" : "B",
}

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

Чтобы решить эту проблему, просто добавьте c в свое состояние и задайте ему правильное начальное значение.

например,

state = {
    "a" : "A",
    "b" : "B",
    "c" : "C", // added and initialized property!
}

Надеюсь, я смог объяснить свой крайний случай.

вот так

value={this.state.fields && this.state.fields["name"] || ''}

у меня работает.

Но я установил начальное состояние так:

this.state = {
  fields: [],
}

Я столкнулся с тем же предупреждением, используя перехватчики реакции, Хотя я уже инициализировал начальное состояние раньше как: -

const [сообщение, setPost] = useState ({title: "", body: ""})

Но позже я переопределил часть предопределенного объекта состояния в обработчике события onChange,

 const onChange=(e)=>{
        setPost({[e.target.name]:e.target.value})
    }

Решение Я решил это, скопировав сначала весь объект предыдущего состояния (с помощью операторов распространения), а затем отредактировав его поверх него,

 const onChange=(e)=>{
        setPost({...post,[e.target.name]:e.target.value})
    }

Измените это

  const [values, setValues] = useState({intialStateValues});

для этого

  const [values, setValues] = useState(intialStateValues);
const [name, setName] = useState()

выдает ошибку, как только вы вводите в текстовое поле

const [name, setName] = useState('') // <-- by putting in quotes 

исправит проблему в этом примере строки.

Внутри компонента разместите поле ввода следующим образом.


Поместите пустое значение, если значение не существует или нулевое.

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

Сначала установить текущее состояние ... this.state

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

this.setState({...this.state, field})

Если в вашем состоянии есть объект, вы должны установить состояние следующим образом: Предположим, вам нужно указать имя пользователя внутри объекта пользователя.

this.setState({user:{...this.state.user, ['username']: username}})

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

constructor(props){
    super(props)
    this.state = {
        user:{
            email:'',
            password:''
        }
    }
}

// This handler work for every input field
changeHandler = event=>{
    // Dynamically Update State when change input value
    this.setState({
        user:{
            ...this.state.user,
            [event.target.name]:event.target.value
        }
    })
}

submitHandler = event=>{
    event.preventDefault()

    // Your Code Here...
}

render(){
    return (
        
) }

2022 WebDevInsider