Just_Ice
Just_Ice

Reputation: 563

How to share same function with multiple react components?

I have a situation where I am sharing the same function with multiple react components.

I have multiple components which are time dropdowns. Whenever a new value is selected on the dropdown, the onTimeChange function is called correctly with the selected time being returned.

However, there is no way for me to know if the first time dropdown value was changed or the last. Ideally, I would like to update the value of state depending on which dropdown was changed.

How do I go about fixing this?

export default () => {

    const onTimeChange = (time) => {
        console.log(time);
        //change state for the dropdown changed
    }

    return (
         <TimeDropdown onTimeChange={onTimeChange}/>
         <TimeDropdown onTimeChange={onTimeChange}/>
         <TimeDropdown onTimeChange={onTimeChange}/>
         <TimeDropdown onTimeChange={onTimeChange}/>
         <TimeDropdown onTimeChange={onTimeChange}/>
         <TimeDropdown onTimeChange={onTimeChange}/>
    )


}

Upvotes: 0

Views: 1740

Answers (2)

bozdoz
bozdoz

Reputation: 12890

I might do something like this:

// render this many dropdowns
const dropdowns = 3;

function App() {
  // onTimeChange accepts two arguments
  const onTimeChange = (time, index) => {
    console.log(time, index);
    //change state for the dropdown changed
  };

  // create array from dropdowns to more easily manage number of TimeDropdowns
  return Array.from({ length: dropdowns }).map((_, i) => (
    <TimeDropdown onTimeChange={onTimeChange} key={i} iteration={i} />
  ));
}

// example dropdown values
const values = [1, 2, 3, 4, 5];

class TimeDropdown extends React.Component {
  render() {
    return (
      {/* call instance function, NOT passed/props function */}
      <select onChange={this.handleTimeChange}>
        <option />
        {values.map(value => (
          <option key={value} value={value}>
            {value}
          </option>
        ))}
      </select>
    );
  }

  handleTimeChange = e => {
    // call function passed by props
    this.props.onTimeChange(e.target.value, this.props.iteration);
  }
}

ReactDOM.render(<App />, document.getElementById("app"));

Doing something like this will create single instances of these functions; e.g. by contrast, this creates a NEW function:

<TimeDropdown onTimeChange={(e) => onTimeChange(e, 1)} />

Check out a demo: https://codepen.io/bozdoz/pen/WNegpjG?editors=0011

Upvotes: 2

Shailendra Sahu
Shailendra Sahu

Reputation: 131

you can do it by passing an index argument in the onTimeChange function and while passing this function to muliple TimeDropDown components, every component will call this onTimeChange function with particuar index value and depending on the index value you can do changes in the state

export default () => {

 const onTimeChange = (time, index) => {
   console.log(time);
   if (index === 'value1'){
     //changes in the state using setState
   }
   if (index === 'value2'){
     //different changes in the state using setState
   }
 }
 return (
     <TimeDropdown onTimeChange={(event) => {onTimeChange(event, '1')}/>
     <TimeDropdown onTimeChange={(event) => {onTimeChange(event, '2')}/>
     <TimeDropdown onTimeChange={(event) => {onTimeChange(event, '3')}/>
     <TimeDropdown onTimeChange={(event) => {onTimeChange(event, '4')}/>
  )
}

Upvotes: 3

Related Questions