dcsan dcsan - 3 months ago 13
React JSX Question

tracking down Each child in an array or iterator should have a unique "key" prop

I often get this error while doing stuff in react, and it's hell to try and track down where the problem is. Does anyone have tips for digging through your UI to find these cases?

Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `Constructor`. See https://..... /react-warning-keys for more information.


I've started just adding
key={Math.random}
to divs - is there any reason NOT to do this? React just needs any unique key?

If this is the case, I'm not sure why the framework doesn't just do that internally; they're already generating pseudonames for each of the DIVs it seems...

The error messages aren't very helpful in indicating where the problem is:

warning @ react-dev.js:18780validateExplicitKey @ react-dev.js:9316validateChildKeys @ react-dev.js:9378createElement @ react-dev.js:9483render @ Editor.tsx:245_renderValidatedComponentWithoutOwnerOrContext @ react-dev.js:5943_renderValidatedComponent @ react-dev.js:5963ReactCompositeComponent__renderValidatedComponent @ react-dev.js:12346_updateRenderedComponent @ react-dev.js:5916_performComponentUpdate @ react-dev.js:5900updateComponent @ react-dev.js:5829ReactCompositeComponent_updateComponent @ react-dev.js:12346performUpdateIfNecessary @ react-dev.js:5777performUpdateIfNecessary @ react-dev.js:13036runBatchedUpdates @ react-dev.js:13734perform @ react-dev.js:15623perform @ react-dev.js:15623perform @ react-dev.js:13691flushBatchedUpdates @ react-dev.js:13752ReactUpdates_flushBatchedUpdates @ react-dev.js:12346closeAll @ react-dev.js:15689perform @ react-dev.js:15636batchedUpdates @ react-dev.js:8455enqueueUpdate @ react-dev.js:13781enqueueUpdate @ react-dev.js:13371enqueueSetState @ react-dev.js:13537ReactComponent.setState @ react-dev.js:5204(anonymous function) @ Editor.tsx:100v @ zepto.min.js:2S.onreadystatechange @ zepto.min.js:2
OptionPicker.tsx:44template.initValue spot_intro

Answer

The reason for that is called reconcilliation and it's explained in react's Multiple Components doc page:

When React reconciles the keyed children, it will ensure that any child with key will be reordered (instead of clobbered) or destroyed (instead of reused).

If you use Math.random, you'll get a different id every time so react won't be able to do its trick. This very example appeared in react's github issues and as Paul O’Shannessy pointed:

  • key is not really about performance, it's more about identity (which in turn leads to better performance). randomly assigned and changing values are not identity
  • We can't realistically provide keys without knowing how your data is modeled. I would suggest maybe using some sort of hashing function if you don't have ids
  • We already have internal keys when we use arrays, but they are the index in the array. When you insert a new element, those keys are wrong.

I'd suggest you read the aforementioned thread.