Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Making simple React handleChange() function into Higher Order Function

function CheckoutForm({ onSubmit }) {
  const [shippingName, setShippingName] = useState("");
  
  function handleChange(func, e) {
    return function () {
      return func.call(null, e.target.value);
    };
  }
  
  return (
    <form>
      <div className="field">
        <label htmlFor="shipping-username">이름</label>
        <input
          id="shipping-username"
          type="text"
          name="shipping-username"
          autoComplete="off"
          value={shippingName}
          // onChange={(e) => setShippingName(e.target.value)} <--- ORIGINAL METHOD
          onChange={handleChange(setShippingName(e.target.value), e)} <--- MY QUESTION
        />
      </div>
    </form>
  )
}

While making a simple input field, I was curious if I could create a higher order handleChange function and reuse it for other inputs. I know there is a better way using computed property names, but just out of curiosity.

The error message I get from above code is that e is not defined and I am stuck here. Any advice is welcomed.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

When you define an onChange handler like this:

onChange={handleChange(setShippingName(e.target.value), e)}

You’re assigning the returned value of this handleChange call as the handler. You must therefore pass in your own values to handleChange, because it doesn’t get called during the event — e won’t be defined at this point. It’s only the resulting function that will receive e from the event.

So you could re-define handleChange with e as the argument to the inner function, like this:

  function handleChange(func) {
    return function (e) {
      return func.call(null, e.target.value);
    };
  }

And further down you can skip passing e (which woud be undefined anyway). Rather just do like this:

onChange={handleChange(setShippingName)}

…however, I think you can greatly simplify everything by just defining your handler inline like this:

onChange={(e) => setShippingName(e.target.value)}

^^ this is the way everyone does it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading