You can find offending part by looking for map
calls in your jsx. Each top-level element inside map should have key
property, i.e.
{items.map(item => (
<div key={item.id}>
<div>{item.name}</div>
<div>{item.description}</div>
</div>
))}
Docs have some explanations on the subject, in particular:
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity
The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys
When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort
We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state.
UPD
If you want to use Math.random
, I think the better solution might be using UUIDv4. For example, this package can generate them. While theoretically it is possible to generate two similar UUIDs, chance is very low and you need to generate a lot in seconds (some numbers). However, I never did that and can't say how much using UUID as key impacts performance. Given what documentation says about keys, I guess react will always think that all elements were removed and new ones added.
So the best solution is to have some id associated with each item. If you render an array of unique strings, item itself can be the key. If items in array do not have any unique id and order of items is never changed and items can not be removed from array, using index
should be a safe option. And as last resort you can try uuid.
UPD2
As regards to finding offensive code, I noticed that there is a trace in this warning, looking like this:
index.js:1375 Warning: Each child in a list should have a unique "key" prop.
Check the render method of `Log`. See https://*b.me/react-warning-keys for more information.
in div (at Log.js:241)
in Log (created by ConnectFunction)
in ConnectFunction (at HomePage.js:10)
in WithWorkspace (created by ConnectFunction)
in ConnectFunction (at HomePage.js:8)
in HomePage (at App.js:24)
in Route (at AuthenticatedRoute.js:14)
in AuthenticatedRoute (created by ConnectFunction)
in ConnectFunction (at App.js:23)
in Switch (at App.js:22)
in div (at App.js:21)
in div (at App.js:18)
in Unknown (created by ConnectFunction)
in ConnectFunction (at FetchAll.js:165)
in Unknown (created by ConnectFunction)
in ConnectFunction (at FetchAll.js:164)
in Unknown (created by ConnectFunction)
in ConnectFunction (at FetchAll.js:163)
in FetchAll (at App.js:17)
in Router (created by BrowserRouter)
in BrowserRouter (at App.js:15)
in App (at src/index.js:14)
in Provider (at src/index.js:13)
Here offending file is named Log.js
, line 241. I don't know if trace is always present and correct but it might help.
As for me, I check result in browser very often and console usually is open, so when I see that warning, I usually know what I did with arrays just recently and where I forgot the key.