Case 1:
I set specify option value selectedZone
to my <DropDownMenu />
it works fine.
<DropDownMenu />
is my selector:
render() {
let { zone, selectedZone, selectedCity } = this.state;
return (
<DropDownMenu
style={{
selectedOption: {
marginBottom: -5
}
}}
styleName="horizontal"
options={zone}
selectedOption={selectedZone || zone[0]}
onOptionSelected={(zone) => {
this.setState({ selectedZone: zone, selectedCity: zone.children[0] });
}}
titleProperty="brand"
valueProperty="id"
/>
...
)
}
Case 2:
When I specify the value selectedZone
from my AsyncStorage (The value is the same) it doesn't work and show yellow warnning.
So I try to check the source code.
The function getSelectedOption()
from <DropDownMenu />
source code.
getSelectedOption() {
const { options, selectedOption } = this.props;
console.log('check options');
console.log(options);
console.log('check selectedOption');
console.log(selectedOption);
console.log('check _.indexOf(options, selectedOption');
console.log(_.indexOf(options, selectedOption));
if (_.indexOf(options, selectedOption) === -1) {
console.warn(
`Invalid \`selectedOption\` ${JSON.stringify(selectedOption)}, ` +
'DropDownMenu `selectedOption` must be a member of `options`.' +
'Check that you are using the same reference in both `options` and `selectedOption`.'
);
return;
}
return selectedOption;
}
lodash function indexOf will return 1 in Case 1.
rerun -1 in Case 2, I think it should return 1 just like Case 1
I compare with options
and selectedOption
can't see what is different in Case 1 and Case 2.
Some one can teach me what step I miss it ?
Any help would be appreciated. Thanks in advance.
When I specify the value selectedZone from my AsyncStorage (The value is the same) it doesn't work and show yellow warnning.
Lodash has very little to do with this - it comes down to how JavaScript compares objects - two of them are the same ONLY if they are literally the same underlying object:
const a = {name: "fred"};
const b = a; //literally the same object
const c = {name: "fred"}; //an object that looks the same
console.log("a, b, c", a, b, c);
console.log("a === b", a === b);
console.log("a === c", a === c);
Two objects with the same values which are different objects are not considered the same. At least, not according to indexOf
, as it uses the JavaScript comparison:
const arr = [
{name: "alice"},
{name: "bob"},
{name: "carol"}
];
const originalObject = arr[1]; //literally the same object
const newObject = {name: "bob"}; //an object that looks the same
const indexWithOriginalObject = _.indexOf(arr, originalObject);
const indexWithNewObject = _.indexOf(arr, newObject);
console.log("index when using the original object:", indexWithOriginalObject);
console.log("index when using a new object that looks the same:", indexWithNewObject);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
However, you can use the Lodash method findIndex
that will correctly do the comparison.
const arr = [
{name: "alice"},
{name: "bob"},
{name: "carol"}
];
const index = _.findIndex(arr, {name: "bob"});
console.log("index", index);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
A word of warning - invoking findIndex
with only an object will only check the properties you supplied. So it may not find the exact object you want, if you have more than one that look the same. You can use isEqual
in a callback if you want to check that the two objects look EXACTLY the same
const arr = [
{name: "alice"},
{name: "bob", lastName: "bloggs"},
{name: "bob", lastName: "smith"},
{name: "carol"}
];
const indexPartial1 = _.findIndex(arr, {name: "bob"});
const indexPartial2 = _.findIndex(arr, {name: "bob", lastName: "smith"});
const indexEqual1 = _.findIndex(arr, x => _.isEqual(x, {name: "bob"}));
const indexEqual2 = _.findIndex(arr,x => _.isEqual(x, {name: "bob", lastName: "smith"}));
console.log(
"index by partial equality where the argument only has one property:",
indexPartial1
);
console.log(
"index by partial equality where the argument has both properties:",
indexPartial2
);
console.log(
"index by full equality where the argument only has one property:",
indexEqual1
);
console.log(
"index by full equality where the argument has both properties:",
indexEqual2
);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>