Using 2.0.0, I am still getting an error when I use object values with string labels.
This is the error I get:
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.
I created a sandbox showing the behavior here.
Just select 'Option1' and 'Option 2' and it will emit the error to the console.
I'm no expert, but taking a look at your example makes me assume that it's coercing the value
property to a string or something like that (hence [object Object]
?) which wouldn't be unique. what you can do is set the values to be e.g. 1, 2, 3
and then add an additional property called firm
that is the Firm
object
I modified the code sandbox to better mirror my objects. There is an override of the toString method in my code that stringifies the JSON. I put a simpler version in the sandbox, but it has the same effect.
get [Symbol.toStringTag]() {
return this._legalName;
}
Same issue. Actually, if the code DID call toString() it would solve my problem, because the JSON-ified version would definitely be unique.
A better way might be to have a property called uniqueKey, which would be the name of a property on the object that uniquely identifies it.
<Select
className="basic-single"
classNamePrefix="select"
isMulti={true}
name="firm"
options={firmOptions}
uniqueKey="firmId"
/>
In the component's code, the react key variable would then map to value[uniqueKey].
I'm not sure I follow you with the additional property bit. What would I add the property to?
I can see using a unique ID as the value, then using that to lookup the value when the event is called, but that is very inefficient (there are thousands of values right now, there will be many more soon).
Looks like the value should not be an object. Try to provide options like this: { value: "Option 1", label: "Option 1", data: new Firm({ legalName: "Option 1" }) },
And then use the data field to access your object, and value would contain some unique key. Worked in my case to get rid of these warnings.
Hi, the issues seems to be still open as I'm facing it. @robotanz suggestion seems fine but still I think it is good to have a fix in the repo itself. Can a prop like toString
or customKey
be passed so when it's provided something like customKey(value)
be set instead of value itself as the key?
I think that's the simple solution for fixing this bug.
I found that if I define getOptionValue
, I can still keep the value an object but have react-select generate unique keys for the options.
For example, I am doing something like this:
const TestSelect = props => {
const { testOptions } = props;
const options = testOptions.map(test =>
({label: test.name, value: {id: test.id, name: test.name}})
)
const getOptionValue = option => option.value.id;
const handleChange = option => setValue(option.value)
return (
<Select {...{ ...props, options, getOptionValue, handleChange }} />
);
};
to solve this: I just added a toString()
method in the objects I pass as a value to react-select, so I can tell it how to create a key for that specific value
/** useSpreadsheetData.ts */
import { useEffect, useState } from "react"
import { parse } from "papaparse"
type Entry = {
view_name: string
field_name: string
table_name: string
}
const url = "someurl"
export const useSpreadsheetData = () => {
const [state, setState] = useState<ReadonlyArray<Entry>>([])
useEffect(
() =>
parse(url, {
header: true,
download: true,
complete: response => setState(response.data),
}),
[]
)
return state
}
/** SelectFields.tsx */
import * as React from "react"
import Select from "react-select"
import { useSpreadsheetData } from "./useSpreadsheetData"
export const SelectFields = props => {
const state = useSpreadsheetData()
return (
<Select
isMulti
onChange={props.onChange}
options={state.map(value => ({
value: {
...value,
/**
* The method above is to avoid React Select from spamming
* the console with key errors since it is using this object
* as a value for every select option
**/
toString: () => `${value.field_name}-${value.view_name}`,
},
label: `${value.table_name} (${value.view_name})`,
}))}
/>
)
}
Hello -
In an effort to sustain the react-select
project going forward, we're closing old issues.
We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our efforts towards the current major version.
If you aren't using the latest version of react-select
please consider upgrading to see if it resolves any issues you're having.
However, if you feel this issue is still relevant and you'd like us to review it - please leave a comment and we'll do our best to get back to you!
Most helpful comment
Looks like the value should not be an object. Try to provide options like this:
{ value: "Option 1", label: "Option 1", data: new Firm({ legalName: "Option 1" }) },
And then use the data field to access your object, and value would contain some unique key. Worked in my case to get rid of these warnings.