3
votes

I'm trying to handle changes in my form. I have title, description, and category.

The first input(title) -> Unable to type in the field.

The second input(description) -> Able to type in field but result is undefined.

The 3rd input(category DDL) -> Unable to change selected category, but default selected is being outputted in my alret as 'drink';

Problem:

AddDeal is changing a controlled input of type text to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.

I have viewed the react document here on controlled components but finding it hard to understand as I'm new to it.

https://facebook.github.io/react/docs/forms.html#controlled-components

Here is my code for AddDeal.js

export default class AddDeal extends React.Component {
  constructor(props) {
    super(props);

    // Set the state
    this.state = {
      title: '',
      description: '',
      category: 'technology'
    };

    this.onSubmit = this.onSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  onSubmit(e) {
    e.preventDefault();

    alert('Title is: ' + this.state.title + 'Description is: ' + this.state.description + 'Category is: ' + this.state.category);
  }

  handleChange(e) {
    this.setState({
      title: e.target.title,
      description: e.target.description,
      category: e.target.value
    });
  }

  render() {
    return (
    <div>
      <h1>Add Deal</h1>
      <form onSubmit={this.onSubmit}>
        <label><input value={this.state.title} onChange={this.handleChange} type="text" name="title"/></label>
        <label><input value={this.state.description} onChange={this.handleChange} type="text" name="description" /></label>
        <select value={this.state.category} onChange={this.handleChange}>
            <option value="technology">Technology</option>
            <option value="food">Food</option>
            <option value="drink">Drink</option>
            <option value="books">Books</option>
          </select>
        <input type="submit" value="Submit"/>
      </form>
    </div>
    );
  }
}

Why is this so hard to grab inputs? Should I be using props instead of state? Thanks.

2
Sorry I never saw this post, but after reading through it, using state for handling inputs is becoming alot clearer. Thank youcala

2 Answers

6
votes

Problem is in onChange function, you are using common onChange function so instead of updating all with same value update the specific state value.

Use this function:

handleChange(e) {
    this.setState({
        [e.target.name] : e.target.value
    }); 
}

Use name property to update the specific state, and you need to define the name='category' with select field.

Check the working example:

class AddDeal extends React.Component {
  constructor(props) {
    super(props);

    // Set the state
    this.state = {
      title: '',
      description: '',
      category: 'technology'
    };

    this.onSubmit = this.onSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  onSubmit(e) {
    e.preventDefault();

    alert('Title is: ' + this.state.title + 'Description is: ' + this.state.description + 'Category is: ' + this.state.category);
  }

  handleChange(e) {
    this.setState({
        [e.target.name] : e.target.value
    });
  }

  render() {
    return (
    <div>
      <h1>Add Deal</h1>
      <form onSubmit={this.onSubmit}>
        <label><input value={this.state.title} onChange={this.handleChange} type="text" name="title"/></label>
        <label><input value={this.state.description} onChange={this.handleChange} type="text" name="description" /></label>
        <select name='category' value={this.state.category} onChange={this.handleChange}>
            <option value="technology">Technology</option>
            <option value="food">Food</option>
            <option value="drink">Drink</option>
            <option value="books">Books</option>
          </select>
        <input type="submit" value="Submit"/>
      </form>
    </div>
    );
  }
}

ReactDOM.render(<AddDeal/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>
0
votes

change your function to

 handleChange(e) {
    this.setState({
        [e.target.name] : e.target.value
    }); 
}