how to add multiple onChange in react for single input element

Viewed 2579

I'm having a trouble of handling state-management and event management together on a single input element.

    import React, { Component } from 'react';

export class profileDetail extends Component {
    continue = (e) => {
        e.preventDefault();
        this.props.nextStep();
    };

    back = (e) => {
        e.preventDefault();
        this.props.prevStep();
    };
    render() {
        const { values, handleChange } = this.props;

        const imageHandler = () => {

            //Do this thing..
            //make this magic happen...
        };
        return (
            <div>
                Add your Profile Picture:
                <input
-----HERE------>    onChange={handleChange('ProfilePic')}
      &             defaultValue={values.ProfilePic}
-----HERE------>    onChange={imageHandler}
                    type="file"
                    name="inpFile"
                    id="inpFile"
                    accept="image/*"
                />
            </div>
        );
    }
}

export default profileDetail;

if i add two onChange on single input as above either i happen to get the state management working or either its the DOM manipulation with the onchange that gets working but not the both.

So, how and what changes should i make to get it working properly?

5 Answers

Try using them both in the same function like onChange.

Also, note that the component's name should be Uppercased so it won't be treated as HTML element.

export class ProfileDetails extends Component {

  imageHandler = () => {
    /* ... */
  };

  onChange = () => {
    this.imageHandler();
    this.props.handleChange("ProfilePic");
  };

  render() {
    const { values } = this.props;

    return (
      <input
        onChange={this.onChange}
        defaultValue={values.ProfilePic}
        type="file"
        name="inpFile"
        id="inpFile"
        accept="image/*"
      />
    );
  }
}

export class profileDetail extends Component {
    continue = (e) => {
        e.preventDefault();
        this.props.nextStep();
        imageHandler = imageHandler.bind(this);
    };

    back = (e) => {
        e.preventDefault();
        this.props.prevStep();
    };
   const imageHandler = () => {

        //Do this thing..
        //make this magic happen...

        //and then call outer handler
        this.props.handleChange('ProfilePic');
    };
    render() {
        const { values } = this.props;

        return (
            <div>
                Add your Profile Picture:
                <input
                    defaultValue={values.ProfilePic}
                    onChange={imageHandler}
                    type="file"
                    name="inpFile"
                    id="inpFile"
                    accept="image/*"
                />
            </div>
        );
    }
}

You could use a anonymous function to combine the two methods you want to call into one handler:

<input
  onChange={() => {
    handleChange('ProfilePic');
    imageHandler();
  }}
  defaultValue={values.ProfilePic}
  type="file"
  name="inpFile"
  id="inpFile"
  accept="image/*"/>

You can create a single function which could handle both the things for you onChange:

<input
  onChange={() => {
    handleChange('ProfilePic');
    imageHandler();
  }}
  {...props}
/>

You could just create a commonHandleChange function that does both the actions, your code would look like below.

export class profileDetail extends Component {
   continue = (e) => {
     e.preventDefault();
     this.props.nextStep();
   };

   back = (e) => {
    e.preventDefault();
    this.props.prevStep();
   };

   const commonHandleChange = () => {
       // You can add conditions on which you want to execute both functions here, if you want to execute both function together.
       handleChange('ProfilePic');
       imageHandler();
   };
   render() {
      const { values } = this.props;

      return (
        <div>
            Add your Profile Picture:
            <input
                defaultValue={values.ProfilePic}
                onChange={commmonHandleChange}
                type="file"
                name="inpFile"
                id="inpFile"
                accept="image/*"
            />
        </div>
      );
  }
}
Related