3

In an example of the React docs page Forms, ES6 computed property syntax is used in a method to set the state of the name property.

handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

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

Based on my reading of how the computed property works, it seems like the reason it's used is so target.name can be changed -- is that so? If that's the case it seems like it would just be easier to change it there in setState rather than changing the value of the name variable.

I'm new to React and struggling to understand how the computed property syntax is applied in this example. Any help would be greatly appreciated.

  • "Why not just use name: value" well because you want property name to be the value of name. Consider const name = 'test'; console.log({[name]: 1}, {name: 1}) – Yury Tarabanko Apr 16 at 16:55
  • This allows the same handler to work for multiple inputs, and each input having its own state. – Felix Kling Apr 16 at 20:24
5

Why use ES6 computed property syntax for object setState?

The computed property syntax allows you to set the key of an object dynamically.

In the case of setState, it allows you to handle different properties of the state with a single setState, and so to reuse the same event handler function on different inputs.

So instead of:

class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

    this.handleIsGoingChange = this.handleIsGoingChange.bind(this);
    this.handleNumberOfGuestsChange = this.handleNumberOfGuestsChange.bind(this);
  }

  // a first handler, for isGoing
  handleIsGoingChange(event) {
    const target = event.target;
    const value = target.checked;

    this.setState({
      isGoing: value
    });
  }

  // a second handler, for numberOfGuests
  handleNumberOfGuestsChange(event) {
    const target = event.target;
    const value = target.value;

    this.setState({
      numberOfGuests: value
    });
  }

  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleIsGoingChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleNumberOfGuestsChange} />
        </label>
      </form>
    );
  }
}

You can shorten it like this:

class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

    this.handleInputChange = this.handleInputChange.bind(this);
  }


  // a single handler, for isGoing and numberOfGuests
  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

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

  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}
3

When you wrap a key with array square brackets it will get the variable name as a key.

If you doesn't the key will be string. So...

let name = 'id';
let obj = { //let obj = {
  [name]:1  // id: 1
};          //};
1

Cause you don't want to set the "name" property, but the property which name is stored in name.

  var name = "test";

  // these are all equal:
  this.setState({ [name]: 1 })
  this.setState({ ["test"]: 1 })
  this.setState({ test: 1 })
1

If you don't use the computed property syntax, your function would always set the name property instead of the computed value from event.target.name, which is what you want. Your state would always look like this:

console.log(this.state);
// -> { name: 'some value' }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.