Reputation: 8759
I have this Dropdown menu instance:
<Dropdown
selection
options={this.state.options}
search
value={value}
onChange={this.handleChange}
onSearchChange={this.handleSearchChange}
/>
and when my backend returns response, which is then set as state and it is structured like this:
"options": [
{
"text": "New York,All Airports (NYC) , USA",
"value": "NYC"
},
{
"text": "New York,Newark Liberty Intl (EWR), USA",
"value": "EWR"
},
{
"text": "New York,John F Kennedy (JFK), USA",
"value": "JFK"
},
{
"text": "New York,La Guardia (LGA), USA",
"value": "LGA"
}
]
...I get this warning:
Warning: flattenChildren(...): Encountered two children with the same key,
1:$BLZ
. Child keys must be unique; when two children share a key, only the first child will be used.
in select (created by Dropdown)
in div (created by Dropdown)
in Dropdown (created by SearchForm)
How do I add keys to these elements to prevent this warning?
Upvotes: 1
Views: 3435
Reputation: 2198
So looking at the code for the Semantic UI source for the dropdown component, the render options function converts your passed in options into a array of DropdownItem components:
renderOptions = () => {
const { multiple, search, noResultsMessage } = this.props
const { selectedIndex, value } = this.state
const options = this.getMenuOptions()
if (noResultsMessage !== null && search && _.isEmpty(options)) {
return <div className='message'>{noResultsMessage}</div>
}
const isActive = multiple
? optValue => _.includes(value, optValue)
: optValue => optValue === value
return _.map(options, (opt, i) => (
<DropdownItem
key={`${opt.value}-${i}`}
active={isActive(opt.value)}
onClick={this.handleItemClick}
selected={selectedIndex === i}
{...opt}
// Needed for handling click events on disabled items
style={{ ...opt.style, pointerEvents: 'all' }}
/>
))
}
the key for this array is set by taking the value prop and appending the index to it:
key={`${opt.value}-${i}`}
which should always be unique since the index is used but there is another part of the code for hidden inputs
renderHiddenInput = () => {
debug('renderHiddenInput()')
const { value } = this.state
const { multiple, name, options, selection } = this.props
debug(`name: ${name}`)
debug(`selection: ${selection}`)
debug(`value: ${value}`)
if (!selection) return null
// a dropdown without an active item will have an empty string value
return (
<select type='hidden' aria-hidden='true' name={name} value={value} multiple={multiple}>
<option value='' />
{_.map(options, option => (
<option key={option.value} value={option.value}>{option.text}</option>
))}
</select>
)
}
in this one the key is set to only the value, not the value plus index.
<option key={option.value} value={option.value}>{option.text}</option>
this might be your problem, if you have duplicate values then the key will not be unique. Double check the options list to make sure you don't have duplicate values.
Upvotes: 2