RedGiant
RedGiant

Reputation: 4748

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>;
    }
}

Upvotes: 4

Views: 4295

Answers (2)

Warren Mira
Warren Mira

Reputation: 242

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

Upvotes: 9

ScottWe
ScottWe

Reputation: 190

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.

Upvotes: 4

Related Questions