react: this.key seems to always be undefined inside a React component

In React 0.12.0 if you attempt to use this.key inside a react component, it is undefined

Simple test case here: http://jsfiddle.net/jg2pd4ob/2/

In 0.11.x you could access this value via this.props.key which has been removed.

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Comments: 32 (5 by maintainers)

Commits related to this issue

Most upvoted comments

Yea, this is by design. We had a note about it in the change log: http://facebook.github.io/react/blog/#changelog

The reason is that the concept of a key is something that is controlled by React internals before your component gets created. The same thing for refs.

You can think about an array of ReactElements as a Map.

A Map is a series of key and value tuples. A React fragment is a series of key and props tuples (and also type and ref). The key is designed to decide what the value is in each slot, but not the actual value itself.

If you’re reading a prop named key you might be overloading the meaning of key or accidentally using it for something unrelated.

This change makes the concept a bit more strict. This helps avoids bugs with transferring props to another component which shouldn’t bring the key and ref along with it. It also helps performance by ensure that types in React internals are consistent and stable.

I would suggest renaming or duplicating the prop name as a possible fix if you really need to access it.

TLDR: key={key} ckey={‘c’+key} // react wants you to build keys, but not use them

100% agree with @dcneiner. The could be clarified better. The first line of the changelog reads:

key and ref moved off props object, now accessible on the element directly

The refs are accessible yes but not the key. Confusing.

For future reference, if you are creating a set of JSX elements with array.map(item, index) and want to pass key as a prop e.g. <MyElement key={index} />, just name the prop something else, e.g. <MyElement accessibleKey={index} /> and it won’t be undefined when accessed from the component.

Curious how would you use such an ID? Generally speaking, if you’re debugging where an element comes from, React DevTools helps a lot.

I have just finished schooling and am making my first websites from the ground up. This was just an idea that popped into my head that seemed like it could be very useful. I have little experience going deep into debugging so it very well may be that this idea is unneeded even though it sounds really useful to me in concept. In the future, if it proves to be useful in a way that can’t be accomplished through DevTools or other things, I’ll bring it up. Take care and happy coding.

@gaearon Thank you for explaining it further. After looking at your example again along with your explanation on locality, this concern makes much more sense to me than previously. My sole interest in using key was my use cases 1 & 2 which I don’t think I explained that clearly. They are the same use case, which is to have a nice naming system for the html element id’s within components. My use case 2 just describes how that naming system can be assured to be unique among any component (parent or children) and not just siblings. I liked this naming system because it’s descriptive in that it gives you a “bread-crumb” trail of the full ancestry of any component since it has all past component’s id’s tacked on to it.

But this is practically the only situation I can think of where key is used elsewhere for what it truly represents (which you mentioned earlier): an id that is unique among its sibling components. And as you have shown, this locality issue can spiral into a huge problem. Thanks again for the patience in explaining it to me.

@willdady this.refs is the result of ref assigned to children (not the value), just as the component updating or unmounting is a result of the key assigned to “its associated element”. Element refers to <div /> which is not an instance. key and ref are defined as special use for React and their values should not be used for other purposes.

So to address what seems to be the confusion; <div key="foo" />.key === "foo" is correct, this.key/this.props.key from within a component instance is not.