Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing extra argument to onChange Listener in reactjs

I see that an onChange listener usually doesn't have extra arguments other than e.

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

But is it still possible to pass extra arguments? Like this:

handleOnChange(e,key) {
   this.setState({[key]: e.target.value});
}

I modified the code from this thread to make an example

class FormInput extends React.Component{

    consturctor(props){
       super(props);
       this.state = {email:false,password:false}
    }

    handleOnChange(e,key) {
       this.setState({[key]: e.target.value});
    }

    render() {
          return 
            <form>
              <input type="text" name="email" placeholder="Email" onChange={this.handleOnChange('email')} />
              <input type="password" name="password" placeholder="Password" onChange={this.handleOnChange('password')}/>
              <button type="button" onClick={this.handleLogin}>Zogin</button>
            </form>;
    }
}
like image 521
RedGiant Avatar asked Dec 10 '22 15:12

RedGiant


2 Answers

A few ways to do this:

  1. Add an attribute/or access the attribute from the element

Using this code:

class FormInput extends Component{
      onChange(e) {
          const { target } = e;
          const key = target.getAttribute('name');
      }
}
  1. Bind the extra attribute (partials) when you create the onChange function

Using this code:

<input name='password' onChange={this.onChange.bind('password')} />
//or
<input name='password' onChange={(e) => this.onChange('password',e)} />

Do note that you would need to change the order of the onChange function

onChange(key,e) {
   //key is passed here
}

This is usually not advisable because you would create the function on each render call. See if its fine on your case

  1. List item

Lastly you can wrap the element and from there just pass what the caller needs on the onChange

class Input extends Component {

       dispatchOnChange(e) {
           const { props } = this;
           const { name } = props;
           const value = e.target.value;
           props.onChange(name,value);
       }

       render() {
           return <input {...this.props} onChange={this.dispatchOnChange}/>
       }
   }

   //your render
   <Input type="password" name="password" placeholder="Password" onChange={this.handleOnChange}/>

Hope this helps

like image 58
Warren Mira Avatar answered Dec 27 '22 17:12

Warren Mira


You could create an anonymous function, calling handleOnChange with your custom key. That would look like:

<button type="button" onClick={(e) => this.handleLogin(e, index)}>

If you have not worked with anonymous functions before, this is telling JavaScript to create a new function on the fly during render, that takes a parameter e and calls this.handleLogin(e, index). In JavaScript, anonymous functions inherit scope, so the "this" keyword will be scoped correctly.

like image 38
ScottWe Avatar answered Dec 27 '22 17:12

ScottWe