3

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?

2
  • its because your attrs get converted into props, and the code behind this there is a javascript object, and you cant have two identical keys. you need to defined a single event handler, that can call both actions you require. Commented May 6, 2020 at 13:50
  • You definitely don't need two click handlers, you may set your state changes inside imageHandler body Commented May 6, 2020 at 13:50

5 Answers 5

2

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/*"
      />
    );
  }
}

Sign up to request clarification or add additional context in comments.

5 Comments

by your method i manged to get the functionality working but the state management wasnt working at all. could you please check this detailed version of the current example here and suggest me on what should i do to get this working?
I don't know what "state management wasn't working at all" means without practical example, there are many mistakes in the link you shared, you should ask another question instead, due to: 1. It's out of the scope of current one. 2. Its too much information for a comment.
by state-management i mean the handleChange wasnt working correctly. i also have another short example exactly like it well under the scope of this question but it doesn't work exactly like what you suggested. can you please tell me where I'm wrong?
im not sure why this was up voted, you shouldn't define functions in the render method - or they will get redefined each render.
@developer Good point, fixed. Also, the component name needs to be uppercased.
1

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/*"/>

1 Comment

by your method i manged to get the functionality working but the state management wasnt working at all. could you please check this detailed version of the current example here and suggest me on what should i do to get this working?
0
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>
        );
    }
}

2 Comments

i think you also would need to bind your imageHandler, so ive included: imageHandler = imageHandler.bind(this); in the constructor
hi @developer i managed to get the functionality working but not the state-management. can you please check this detailed code and suggest me what changes should i make?
0

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

Comments

0

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

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

1 Comment

by your method i manged to get the functionality working but the state management wasnt working at all. could you please check this detailed version of the current example here and suggest me on what should i do to get this working?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.