nkbt / react-debounce-input

React component that renders Input with debounced onChange

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

event.currentTarget is null

aaronbeall opened this issue · comments

When handling the onChange event the currentTarget is null.

You can see an example on webpackbin here:

<DebounceInput
  minLength={2}
  debounceTimeout={300}
  onChange={event => {
    console.log("target =", event.target);
    console.log("target.value =", event.target.value);
    console.log("currentTarget =", event.currentTarget);
   }} />

Which gives you the following output after typing "test":

target = <input type=​"text" value data-reactid=​".0.0">​
target.value = test
currentTarget = null

I take it this is because the event is stored then re-dispatched later, and React nulls out the currentTarget after the initial dispatch. However this is not what I would expect because its not how the event argument normally works, you expect currentTarget to be the target you added the handler to.

Seems reasonable, but the event argument is already patched in some cases with {target: {value}}. I would say that given the way this works the onChange callback with an event arg is a little misleading, since it receives a stale event argument. Maybe it makes more sense to just invoke with your own argument, ie onChange(newValue) or onChange(newValue, lastEvent). That's a breaking API change so I'm not expecting you to do this, but that's just my thought. :)

It is how it was before (prev major version), but this component is now mostly used as drop-in replacement for inputs, so current API is something we are quite happy with. Since we do not do mutable DOM operations, we never used either target or any other attribute of event like currentTarget and I would prefer not to do modifications to the original React event (updating target.value is an essential and naturally expected patch)

Maybe adding something about it to the README would be good, tho. If you are keen to PR...

Yes I like that it's mostly a drop-in replacement for <input>. This was just a gotcha I struggled with.

So just trying to understand here, you say you never used target? How should you query the changed value then?

I meant target DOM, obviously we do onChange({target: {value}}) {this.setState({value})} or smth similar in any other code. Just never touch the DOM.

OK, sorry not clear how the DOM relates, patching the React event { currentTarget: { value } } seems like the same thing as patching { target: { value } } to me, but it would be needed in all cases which I understand is more intrusive, and event.target.value is a clean workaround. A simple mention about this in docs sounds fair to me.

BTW, the reason I ran into this is because the React event interface in TypeScript specifies the type of currentTarget (because that type is known based on what the handler is attached to, an HTMLInputElement in this case) while the target cannot be predicted due to bubbling. So you can either use currentTarget.value because .value is a known prop of the current target (the input) or use a type assertion (target as HTMLInputElement).value. Usually you want currentTarget but this is an atypical case.