Setting Picker Item key prop causes keys to be coerced to a string regardless of the actual type
- Dominant language
- TypeScript
- Stars
- 15.9k
- Forks
- 1.6k
- Avg merge
- 3d 9m
- Merged PRs (30d)
- 59
Description
### Provide a general summary of the issue here
The Picker component supports items with numeric id / key props.
### Item.key unset
If the `Item.key` prop is not explicitly set, keys get derived from the `id` or `key` props on the items array.
e.g.
```jsx
function Example() {
let items = [
{ id: 1, name: 'Aardvark' },
{ id: 2, name: 'Cat' },
{ id: 3, name: 'Dog' }, ];
let [animalId, setAnimalId] = React.useState(null);
return (
<>
{ /* Item.key not explicitly set */
(item) => {item.name}
}
Animal id type: {typeof animalId}
);
}
```
The `onSelectionChange` handler will pass a numeric key to `setAnimalId` (consistent with the items data) and `value` + `defaultValue` will work with values of type `number`.
### Item.key explicitly set
If the `Item.key` prop is explicitly set e.g.
```jsx
{item.name}}
```
The `onSelectionChange` will pass a string id to `setAnimalId`, and the `value` + `defaultValue` props will require values of type `string` in order to work.
### 🤔 Expected Behavior?
I would expect in the case of setting `Item.key` prop explicitly:
* `onSelectionChange` should pass the actual value (not the stringified version) of the original id / key
* `value`, and `defaultValue` should be able to match the id / key prop on the items instead of requiring them to be string values
### 😯 Current Behavior
When `Item.key` prop is explicitly set
* `onSelectionChange` passes a stringified value of the original id / key
* `value`, and `defaultValue` don't match the items id / key prop unless they are stringified
### 💁 Possible Solution
_No response_
### 🔦 Context
We have a wrapper component that needs to explicitly set the `Item.key` prop based on properties on the `items`. In cases where these props are `numeric` or `boolean` types, this forces the input `value` + `onSelectedValue` change handlers to work with strings which doesn't match the original data.
### 🖥️ Steps to Reproduce
[https://codesandbox.io/p/sandbox/modern-shadow-znqpwf](https://codesandbox.io/p/sandbox/modern-shadow-znqpwf?file=%2Fsrc%2FApp.js%3A22%2C25&layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522clu8m4b1r00063b6qt0em6lmr%2522%252C%2522sizes%2522%253A%255B100%252C0%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522clu8m4b1r00023b6qa3ncq69w%2522%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522clu8m4b1r00033b6qnvq8g9lk%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522clu8m4b1r00053b6q8rg0tzb0%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B50%252C50%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clu8m4b1r00023b6qa3ncq69w%2522%253A%257B%2522id%2522%253A%2522clu8m4b1r00023b6qa3ncq69w%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clu8m4rnj00513b6q8rkyrj65%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522initialSelections%2522%253A%255B%257B%2522startLineNumber%2522%253A22%252C%2522startColumn%2522%253A25%252C%2522endLineNumber%2522%253A22%252C%2522endColumn%2522%253A25%257D%255D%252C%2522filepath%2522%253A%2522%252Fsrc%252FApp.js%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%252C%2522activeTabId%2522%253A%2522clu8m4rnj00513b6q8rkyrj65%2522%257D%252C%2522clu8m4b1r00053b6q8rg0tzb0%2522%253A%257B%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clu8m4b1r00043b6qt6yqaeqs%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522UNASSIGNED_PORT%2522%252C%2522port%2522%253A0%252C%2522path%2522%253A%2522%252F%2522%257D%255D%252C%2522id%2522%253A%2522clu8m4b1r00053b6q8rg0tzb0%2522%252C%2522activeTabId%2522%253A%2522clu8m4b1r00043b6qt6yqaeqs%2522%257D%252C%2522clu8m4b1r00033b6qnvq8g9lk%2522%253A%257B%2522tabs%2522%253A%255B%255D%252C%2522id%2522%253A%2522clu8m4b1r00033b6qnvq8g9lk%2522%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Afalse%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D)
### Version
3.34.1
### What browsers are you seeing the problem on?
Chrome
### If other, please specify.
_No response_
### What operating system are you using?
MacOS
### 🧢 Your Company/Team
_No response_
### 🕷 Tracking Issue
_No response_
Contributor guide
Research direction
Start with the Picker component and the linked CodeSandbox reproduction, comparing items whose ids are numeric or boolean with and without an explicit Item.key. Done means explicit keys preserve their original value type so onSelectionChange, value, and defaultValue work without stringifying those values; verify against the reported version 3.34.1 behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100