Kerry
Kerry

Reputation: 454

Why this onChange function works?

I am now confused about the onChange event handler. I just want to knows how it works. Traditionally if we want to keep track of value inside the input box or text area we pass a variable to the function.

<InputDialogContent
  inputLabel="Email Address"
  inputType="email"
  onChange={(ev: React.ChangeEvent<HTMLTextAreaElement>): any =>
    onInputChange(ev.target.value)
  }
/>

In this case we are passing in ev.target.value

and the function is

function onInputChange(input: any) {
  if (isValidEmail(input)) {
    setEnableLoginButton(true);
  } else {
    setEnableLoginButton(false);
  }
}

it works fine. I know that The ev.target.value become input But one of my senior change the code into something like this and is still working. I am wondering why its is working when it doesn't pass a variable like the above function

<InputDialogContent
  inputLabel="Email Address"
  inputType="email"
  onChange={onInputChange}
/>

the function become like this. From what i see the function still expecting an variable to be passed into but there is no variable being passed. && THIS FUNCTION STILL WORKS. WHY ?

function onInputChange(e: React.ChangeEvent<HTMLTextAreaElement>) {
  setEnableLoginButton(isValidEmail(e.target.value));
}

const isValidEmail = (email: string): boolean => {
  const validateFormat = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
  if (email.match(validateFormat)) {
    return true;
  } else {
    return false;
  }
};

I am using typescript and its a function component.

Upvotes: 2

Views: 204

Answers (2)

Sergiu Paraschiv
Sergiu Paraschiv

Reputation: 10153

One of them is an inline-defined function, the other is a function passed by reference.

Your InputDialogContent component expects a onChange prop with the signature (event: React.ChangeEvent<HTMLTextAreaElement>): any.

In your first example you are passing an inline-defined function with that signature:

(ev: React.ChangeEvent<HTMLTextAreaElement>): any =>
  onInputChange(ev.target.value)
}

In your second example you are passing the onInputChange function directly. onInputChange has the same signature as required by the onChange prop (that's how you're calling it, a function with a single parameter of type React.ChangeEvent<HTMLTextAreaElement>).

The reason both do the same is that your inline-defined function simply calls onInputChange inside passing it the same parameter, so in essence doing nothing.

You are doing this:

function addNothingToX(x) {
  return x;
}

function addTenToX(x) {
  return x + 10;
}

// all these three are equivalent
console.log(addTenToX(0));
console.log(addNothingToX(addTenToX(0));
console.log(((x) => x)(addTenToX(0)); // this is what you are basically doing

You could do this too:

<InputDialogContent
  onChange={e => setEnableLoginButton(isValidEmail(e.target.value))}
  ...
/>

Upvotes: 1

Peter Lehnhardt
Peter Lehnhardt

Reputation: 4985

Function 1

(ev: React.ChangeEvent<HTMLTextAreaElement>): any => onInputChange(ev.target.value)

has type (ev: React.ChangeEvent<HTMLTextAreaElement>) => void

Function 2

function onInputChange(e: React.ChangeEvent<HTMLTextAreaElement>) {
  setEnableLoginButton(isValidEmail(e.target.value));
}

has type (e: React.ChangeEvent<HTMLTextAreaElement>) => void

Both functions have the same signature (that means you call both functions in the same way), so if the first function is assignable to onChange, then the second function is assignable as well.

From 1 to 2 there are only a couple of simplifications. The first function only gets the event value and passes it down to onInputChange. This can be merged into one function, which happens in example 2.

Upvotes: 1

Related Questions