简体   繁体   中英

Warning: A component is changing an uncontrolled input of type undefined to be controlled

I'm getting a warning:

Warning: A component is changing an uncontrolled input of type undefined to be controlled.

I get the right value in the input field, but it won't let me edit it. I'm dynamically creating these fields in state triggered by a button click.

<input
  className={
    'event-title-input event-input event-main-input input' +
    dat.id
  }
  name={'title' + dat.id}
  value={this.state['title' + dat.id] || ''}
  onChange={this.handleChange}
  style={{ display: 'none' }}
/>

var outerState = this;

  this.state.data.forEach(function(element) {

    var stateTitle = "title" + element.id;
    var stateLocation = "location" + element.id;
    var stateDescription = "description" + element.id;
    var stateStartDate = "startdate" + element.id;
    var stateEndDate = "enddate" + element.id;

    outerState.setState({ [stateTitle]: element.title });
    outerState.setState({ [stateLocation]: element.location });
    outerState.setState({ [stateDescription]: element.description 
});
    outerState.setState({ [stateStartDate]: element.startdate });
    outerState.setState({ [stateEndDate]: element.enddate });
  });
  this.setState({ saveEdit: 'Save'});

If that is the whole component, you seem to be missing a handleChange function. It should probably look something like this:

handleChange(e, id) {
  this.setState({
    ['title' + id]: e.target.value
  });
}

After that, each input should call this function with an id , say:

<input onChange={e => this.handleChange(e, dat.id)} ... />

(I imagine the <input> code is inside some kind of mapping function, but in case you only have one input, it could be made in a more simple way).

Instead of repeatingly call setState you can just set the state at once when the data arrived:

this.setState(
  {
    saveEdit: 'Save',
    ...this.state.data.reduce(
      (result, element) => ({
        ...result,
        ...[
          'title',
          'location',
          'description',
          'startdate',
          'enddate',
        ].reduce((result, key) => {
          result[key + element.id] = element[key];
          return result;
        }, {}),
      }),
      {}
    ),
  },
  current =>
    console.log('current state is now:', current)
);

}

Are you sure every input defaults to an empty string ( value={this.state['title' + dat.id] || ''} )if state is not set?

What does onChange look like?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM