admin管理员组

文章数量:1125551

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.*

Following is my code:

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>
  )
}

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.*

Following is my code:

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>
  )
}
Share Improve this question edited Oct 22, 2019 at 18:59 Bondolin 3,1217 gold badges40 silver badges68 bronze badges asked Oct 30, 2017 at 9:47 Riya KapuriaRiya Kapuria 9,7407 gold badges20 silver badges32 bronze badges 4
  • 4 what is the initial value of fields in state? – Mayank Shukla Commented Oct 30, 2017 at 9:48
  • 2 constructor(props) { super(props); this.state = { fields: {}, errors: {} } this.onSubmit = this.onSubmit.bind(this); } – Riya Kapuria Commented Oct 30, 2017 at 9:50
  • 2 Possible duplicate of React - changing an uncontrolled input – Michael Freidgeim Commented May 7, 2019 at 3:05
  • I just discovered you can use useRef to conditionally set the value to the current input, e.g. value={amountInputFocused ? amountRef.current?.value : amountState}. Not sure if this is by design, but it works, and silences the error. – brandonscript Commented Dec 11, 2021 at 7:27
Add a comment  | 

28 Answers 28

Reset to default 1486

The reason is, in state you defined:

this.state = { fields: {} }

fields as a blank object, so during the first rendering this.state.fields.name will be undefined, and the input field will get its value as:

value={undefined}

Because of that, the input field will become uncontrolled.

Once you enter any value in input, fields in state gets changed to:

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

And at that time the input field gets converted into a controlled component; that's why you are getting the error:

A component is changing an uncontrolled input of type text to be controlled.

Possible Solutions:

1- Define the fields in state as:

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

2- Or define the value property by using Short-circuit evaluation like this:

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

Changing value to defaultValue will resolve it.

Note:

defaultValue is only for the initial load. If you want to initialize the input then you should use defaultValue, but if you want to use state to change the value then you need to use value. Read this for more.

I used value={this.state.input ||""} in input to get rid of that warning.

Inside the component put the input box in the following way.

<input
    className="class-name"
    type= "text"
    id="id-123"
    value={ this.state.value || "" }
    name="field-name"
    placeholder="Enter Name"
/>

In addition to the accepted answer, if you're using an input of type checkbox or radio, I've found I need to null/undefined check the checked attribute as well.

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

And if you're using TS (or Babel), you could use nullish coalescing instead of the logical OR operator:

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

SIMPLY, You must set initial state first

If you don't set initial state react will treat that as an uncontrolled component

that's happen because the value can not be undefined or null to resolve you can do it like this

value={ this.state.value ?? "" }
const [name, setName] = useState()

generates error as soon as you type in the text field

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

will fix the issue on this string example.

As mentioned above you need to set the initial state, in my case I forgot to add ' ' quotes inside setSate();

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

Gives the following error

Correct code is to simply set the initial state to an empty string ' '

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

Set Current State first ...this.state

Its because when you are going to assign a new state it may be undefined. so it will be fixed by setting state extracting current state also

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

If there is an object in your state, you should set state as follows, suppose you have to set username inside the user object.

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

The Best Way to Fix This: Set the Initial State to an Empty String ('') ✨

When creating form inputs in React, it’s important to properly initialize the state. If you leave state properties undefined, React may throw warnings like "uncontrolled input," which can clutter your console with big red error blocks.

本文标签: