Dhanapal
Dhanapal

Reputation: 380

Generic function in react with multiple state variables

How to write a generic function with various state variable change based on the dropdown.

for ex:

I have dropdown 1 and dropdown 2. If I change the

dropdown 1, I need to change the few state variables like a, b, c

dropdown 2, I need to change the few state variables like x, y, z

I can do this with 2 functions. But how to write a a generic function for this?

handleChange: function(e) {
    //api call to xyz.com/getcompany/<company id> to get the job list here
    this.setState({
      selectedCompany: e.target.value,
      companychange: "company changed. New value: " + e.target.value
    })
  },

  handleChange2: function (e) {
    // api call to xyz.com/jobstatus/<job id> to get the job status\(like how many position available for this job\) here
    this.setState({
      jobchange:"job changed. New value " + e.target.value
    })
  }

Codepen: https://codepen.io/asdhanapal/pen/WmwJPj?editors=0011

Upvotes: 0

Views: 1649

Answers (5)

mzedeler
mzedeler

Reputation: 4369

As I read your description of the requirements, there are no functional dependencies between dropdown 1 and dropdown 2, so I'd split this up in two separate components.

Upvotes: 0

David
David

Reputation: 633

Try this:

handleChange: function(source, e) {
switch(source) {
  case 'company': 
      //Need to do api call to get the job list here
      this.setState({
        selectedCompany: e.target.value,
        companychange: "company changed. New value: " + e.target.value
      })
    break;
  case 'job':
      // Need to do api call to get the job status\(like how many position available for this job\) here
      this.setState({
        jobchange:"job changed. New value " + e.target.value
      })
    break;

  };
},

 <select value={this.state.selectedCompany} onChange={this.handleChange.bind(this, 'company')}>
 <select value={this.state.selectedCompany} onChange={this.handleChange.bind(this, 'job')}>

Upvotes: 0

Jonas Wilms
Jonas Wilms

Reputation: 138267

You could use a curried function to simplify the code a bit:

 changeToState(fn) {
    return e => this.setState(fn(e));
 }

 render() {
   //...
   <input onChange={changeToState(e => ({ selectedCompany: e.target.value, /*...*/ }))} />
   <input onChange={changeToState(e => ({ jobChange: e.target.value, /*...*/ }))} />
}

If that is still to much boilerplate, you could extract the handleChange event into a functional component:

 const StateChanger = ({ action, parent, ...props }) => (
   <input onChange={e => parent.setState(action(e))} {...props} />
 );

  // inside a component's render:
   <StateChanger parent={this} action={e => ({ selectedCompany: e.target.value })} style={{ color: red }} />

but as I already mentioned in the comments, that might remove repeated code a bit, but it doesn't improve readability / maintainability whatsoever.

Upvotes: 1

Umair Farooq
Umair Farooq

Reputation: 1823

You can use following:

handleChange = event => {
  const { name, value } = event.target;
  this.setState({
    [name]:value
   })
}
// in input 
<input name="username" onChange={this.handleChange} />

Upvotes: 0

Sudhir Dhumal
Sudhir Dhumal

Reputation: 970

You can use below snippet:

handleChange = event => {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;

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

Reference to react docs section: https://reactjs.org/docs/forms.html#handling-multiple-inputs

Upvotes: 0

Related Questions