React: event.currentTarget.value returns undefined in React 16

Created on 23 Feb 2018  路  4Comments  路  Source: facebook/react

 "react": "^16.2.0",
 "react-dom": "^16.2.0"

Just upgraded to react 16 from 15.0.2, and using event currentTarget.value will give me undefined. Basically I have a stateless child component that will fire the callback when it's clicked, and will pass an extra params through DOM API value field

 <a className="btn-sm" onClick={onDelete} value={data}>
   <i className="fa fa-trash" aria-hidden="true" />
 </a>

And in my parent component the callback is as follows, the param is not accessible in 16 anymore

  onDelete(event) {
    const data = event.currentTarget.value;  //works in react 15.0.2, but returns undefined in 16
    ...
  }

So I looked into the event that is being returned in both versions of React, looks like in 16 the _dispatchInstances is a FiberNode, whereas in 15 is a ReactDOMComponent
screenshot from 2018-02-23 10 44 44
React 16

screenshot from 2018-02-23 10 46 44
React 15

Is this an intentional change? If so, how do I go about passing this params to the callback? I don't really want to use arrow functions since that affects the performance

Most helpful comment

event.currentTarget.getAttribute('value') also seems to work.

All 4 comments

@yidingalan

  1. according spec HTMLAnchorElement doesn't have value property. So do not expect it to work with react. Previous behavior could be a bug.
  2. arrow functions in render do not affect performance in cases like yours.

@TrySound is right. This probably shouldn't have worked in React 15. The reason it did is because value was a whitelisted attribute that was also configured to be set as a property. Which means it was set like:

node.value = value;

Instead of being set as an attribute

node.setAttribute('value', value)

This meant that React was creating a new value property on the element, which probably shouldn't have happened. Now, React sets value as an attribute using setAttribute. Reading event.target.value still works with input elements because the DOM will keep the property in sync with the attribute. Since anchor elements don't have a value property by default, setting the attribute doesn't set the property.

I recommend either using an arrow function (unless you've benchmarked that this is a problem, which is rare) or using a data attribute like data-value.

Hope that helps!

event.currentTarget.getAttribute('value') also seems to work.

Hi there,
i just went through the same problem asking myself what was wrong with me. Looking at official React documentation you have to use event.persist() on SyntheticEvent in order the target property to be filled correctly; this is because it's an asynchronous way to handle events and so, its values are only promise before doing "event.persist()".

There is a better way to handle it: use destructuring on the event object. Instead of referencing the event parameter as (event) => {...} you can reference its target directly using desctructuring as follow: ({ target }) => {...}

Was this page helpful?
0 / 5 - 0 ratings