If you like me are using objects and not strings as values for the options, if you are also using isMulti then react-select will try to set the key prop of every MultiValue with that object causing an error:
Warning: Encountered two children with the same key, `[object Object]`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
in div (created by ValueContainer)
in ValueContainer (created by Component)
in Component (created by Select)
in div (created by Control)
in Control (created by Select)
in div (created by SelectContainer)
in SelectContainer (created by Select)
in Select (created by StateManager)
in StateManager
...
Set a key for each MultiValue, React.cloneElement(child, { key: child.props.children }) this works if the labels for your options are unique. If it's not the case you should choose another value as key.
import Select, { components } from 'react-select';
...
MyValueContainer = ({ children, ...props }) => {
if (children[0].length) {
const newChilds = children[0].map(child =>
React.cloneElement(child, { key: child.props.children })
);
newChilds.forEach((newChild, index) => {
children[0][index] = newChild;
});
// children[0] = newChilds; wont work. children[0] is readonly
}
return <components.ValueContainer {...props}>{children}</components.ValueContainer>;
};
...
<Select
components={{
Option: MyOption,
MultiValueLabel: this.MyMultiValueLabel,
--> ValueContainer: this.MyValueContainer <--
}}
>
Edit: this could be fixed changing https://github.com/JedWatson/react-select/blob/v2/src/Select.js#L1184
If you can set value to a string, this will fix the warning.
I ended up passing the object I needed as a separate field on the options object so that I could still grab the data.
From
{
label: foo.name,
value: foo
}
to
{
label: foo.name,
value: foo.name,
foo: foo
}
Most helpful comment
If you can set
valueto a string, this will fix the warning.I ended up passing the object I needed as a separate field on the
optionsobject so that I could still grab the data.From
to