brownie3003
brownie3003

Reputation: 538

Why am I switching from controlled to uncontrolled input in react

I'm not sure why I'm getting the switch from controlled to uncontrolled input warning. this.state.lineItemName is defined in my constructor which seems to be the main mistake from other SO questions I've read.

This is very similar to the todoMVC implementation for React.

class LineItemForm extends React.Component {
  constructor(props) {
    super(props);
      this.state = {
        newLineItem: ""
      }
  }

  render() {
    return(
      <tr>
        <td>
          <input type="text"
            onChange={this.handleChange.bind(this)}
            onKeyDown={this.handleKeyDown.bind(this)}
            value={this.state.newLineItem}
            placeholder="Search for an item..."
            autoFocus={true}
          />
        </td>
      </tr>
    );
  }

  handleChange(e) {
    this.setState({newLineItem: event.target.value});
  }

  handleKeyDown(e) {
    if (e.keyCode === this.props.ENTER_KEY_CODE || e.keyCode === this.props.TAB_KEY_CODE) {
      e.preventDefault();

      let name = e.target.value.trim();

      if (name) {
        let lineItem = {
          name: name
        };
        this.props.createLineItem(lineItem, this.props.sectionId)
        this.setState({newLineItem: ""})
      }
    } else {
      return;
    }
  }
}

LineItemForm.defaultProps = {
    ENTER_KEY_CODE: 13,
    TAB_KEY_CODE: 9
}

Upvotes: 1

Views: 120

Answers (2)

gnerkus
gnerkus

Reputation: 12019

The warning occurs because of an error in the handler for the onChange event.

Controlled components require a handler for the onChange event. This allows the component to update its value. If the handler does not work, the value cannot be updated via the props and must be set via the value entered by the user.

To fix this error, you'll need to correct the error in the onChange event handler you defined:

// Parameter was renamed to 'event' to reflect its use in the 
// 'setState' method call below
handleChange(event) {
  this.setState({newLineItem: event.target.value});
}

Upvotes: 1

Mani Shooshtari
Mani Shooshtari

Reputation: 780

use

handleChange(event) { this.setState({newLineItem: event.target.value}); }

instead of

handleChange(e) {
    this.setState({newLineItem: event.target.value});
}

Upvotes: 2

Related Questions