1

I have multiple input fields:

<label>
    <span className="codes__input-label">Count</span>
    <input
        type="number"
        value={this.state.count}
        onChange={this.onInputChange}
    />
</label>

<label>
    <span className="codes__input-label">One time Usage</span>
    <input
        type="text"
        value={this.state.distributor}
        onChange={this.onInputChange}
    />
</label>

<label>
    <span className="codes__input-label">One time Usage</span>
    <input
        type="checkbox"
        value={this.state.oneTimeUsage}
        onChange={this.onInputChange}
    />
</label>

It seems repetitive to have one handler for each event, so I want to have one handler for all of them.

What is a good approach?

Here is my best attempt. I get a long TypeScript errors on the setState lines.

onInputChange(event: React.FormEvent<HTMLInputElement>): void {
    switch (event.currentTarget.type) {
        case "number":
            this.setState({[event.currentTarget.name]: event.currentTarget.valueAsNumber});
        break; 
        case "text":
            this.setState({[event.currentTarget.name]: event.currentTarget.value});
        break; 
        case "checkbox":
            this.setState({[event.currentTarget.name]: event.currentTarget.checked});
        break; 
    }
}

1 Answer 1

2

FYI, I don't know Typescript but your problem is not related to this. First thing I see, you don't have name attributes for your input's. So, add them. The second problem is you don't have a checked value for the checkbox, add it, too.

If you haven't already bound onInputChange method, bind it. Then it should work as expected.

<label>
  <span className="codes__input-label">Count</span>
  <input
    name="count"
    type="number"
    value={this.state.count}
    onChange={this.onInputChange}
  />
</label>

<label>
  <span className="codes__input-label">One time Usage</span>
  <input
    name="distributor"
    type="text"
    value={this.state.distributor}
    onChange={this.onInputChange}
  />
</label>

<label>
  <span className="codes__input-label">One time Usage</span>
  <input
    name="oneTimeUsage"
    type="checkbox"
    checked={this.state.oneTimeUsage}
    onChange={this.onInputChange}
  />
</label>

Though, if you don't need valueAsNumber directly and can use the value itself then do some number manipulation, there is a nicer method generally people use for this method.

onInputChange = (e) => {
  const { target, target: { name } } = e;
  const value = target.type === 'checkbox' ? target.checked : target.value;

  this.setState({
        [name]: value
 });
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that is a good answer, I upvote it! But I am still having issues after following your advice: stackoverflow.com/questions/52144584/…
It seems that you have solved your other problems. Doesn't my answer solve your problem with this question?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.