1

I am try to implement event handler function to avoid a new function creation every time the component renders and re-renders.

Scenario1:

If I bind the function in constructor like below and without parameters in onChange it will create a new function in bundle file only once

 constructor(props){
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {
       value: ""
    }
 } 

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

 render(){
    const { value } = this.state;
    return(
      <div>
        <input type="text" onChange={this.handleChange} value={value} />
      </div>
    )
 }

Scenario2:

But when I want to pass some parameters along with event to handleChange function like below I believe it will create a new function every time the component renders and re-renders

 constructor(props){
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {
       value: ""
    }
 } 

 handleChange(e, param1, param2){
    this.setState({
       value: e.target.value
    });
 }

 render(){
    const { value } = this.state;
    return(
      <div>
        <input type="text" onChange={e => this.handleChange(e, param1, param2)} value={value} />
      </div>
    )
 }

So,

how can I write scenario 2 better so that a new function will be created only once in bundle file but not every time the component renders and re-renders? Is it possible?

Edit:

param1 and param2 are my own custom values.

Hemadri Dasari
  • 32,666
  • 37
  • 119
  • 162
  • @OriDrori If I want to pass data value as props I can pass without arrow function but I want to pass event as well along with the params also when we use some external libraries they give id, name which we can't get with event.target.name or id but that needs to be passed like (e, id, name) => this.handleChange(e, id, name) so these cases it will create a new function every time so how to handle such cases is my question – Hemadri Dasari Oct 20 '18 at 09:49
  • I've added an answer that demonstrate your case. As you can see, there's no need for the arrow function. – Ori Drori Oct 20 '18 at 10:33
  • @CertainPerformance - I've reopened the question because the duplicate you've referred to, doesn't actually address the OPs case. – Ori Drori Oct 20 '18 at 10:36

1 Answers1

1

If the target component can pass multiple parameters (input obviously doesn't), your second scenario works without the need of an arrow function:

 render(){
    const { value } = this.state;
    return(
      <div>
        <CustomInput type="text" onChange={this.handleChange} value={value} />
      </div>
    )
 }

Example:

class CustomInput extends React.Component {
  constructor(props) {
    super(props);
    
    this.inputHandleChange = this.inputHandleChange.bind(this);
  }
  
  inputHandleChange(e) {
    this.props.onChange(e, e.target.value.length, 'param2');
  }
  
  render() {
    return (
      <input {...this.props} onChange={this.inputHandleChange} />
    );
  }
}

class InputWrapper extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {
      value: ""
    }
  }

  handleChange(e, param1, param2) {
    console.log(e.target.value, param1, param2);
    
    this.setState({
      value: e.target.value
    });
  }

  render() {
    const {
      value
    } = this.state;
    return (
      <div>
        <CustomInput type="text" onChange={this.handleChange} value={value} />
      </div>
    )
  }
}

ReactDOM.render(
  <InputWrapper />,
  demo
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>


<div id="demo"></div>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209