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.
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.