react-native-picker / picker

Picker is a cross-platform UI component for selecting an item from a list of options.
MIT License
1.5k stars 279 forks source link

onValueChange callback has its arg only accepting string type now #572

Open yuchida0911 opened 3 months ago

yuchida0911 commented 3 months ago

Hello, I would like to see if anyone have had a similar issue.

I have recently upgraded the package from 2.4.10 to 2.6.1. And I just realized that a Picker with which onValueChange callback is set to have something as following does not work as used to.

<Picker
~
onValueChange={(value: number) => setSelected(value)
~
/>

Even when the picker item's value is number, it appears that "value" turns out be casted to string type instead of number type at least for iOS. If my remember correctly, it used to work with the case item value is number without having to have its arg value casted.

When I looked into some recent changes https://github.com/react-native-picker/picker/commit/498b4e313bb7e84bbfa68853b1e988819e6e2e0a I found a part where it could be something to do with it. It looks like it casts its value to string?

#ifdef RCT_NEW_ARCH_ENABLED
- (void)pickerView:(__unused UIPickerView *)pickerView
      didSelectRow:(NSInteger)row inComponent:(__unused NSInteger)component
  withEventEmitter:(facebook::react::SharedViewEventEmitter)eventEmitter
{
    _selectedIndex = row;
      if (eventEmitter != nullptr && _items.count > (NSUInteger)row) {
          std::dynamic_pointer_cast<const facebook::react::RNCPickerEventEmitter>(eventEmitter)
              ->onChange(facebook::react::RNCPickerEventEmitter::OnChange{
                  .newIndex = (int)row,
                  .newValue =  RCTStringFromNSString(RCTNullIfNil(_items[row][@"value"])),
              });
        }
}
#endif

However, it seems that the above implementation should only applicable for the project that the new architecture is enabled, and my project is not. So, I am wondering if someone else has encountered the similar situation.

Thanks for your work!

AdamJB commented 3 months ago

Yes! I just discovered this breaking change today as well. We're using pickers to select number values to do math on it, and it totally broke.

I'm storing a list of numbers in the picker, and when the Picker's onValueChange() is called, it's always a string vs the original number type. This is really bad when you're performing math operations, such as addition, on the value you get back from onValueChange() is a String when you expect a number. Ex: A number of 60 + a picker selected string of "5" = "605" in javascript.

I've recently updated to 2.7.2, and haven't seen any updates in the change log that reflects this issue in newer updates.

yuchida0911 commented 3 months ago

@AdamJB Thanks for confirming, Adam. That is somewhat reassuring to know that I wasn't the only one experiencing that. I would love to take a look into it deeper, however I am no expert on the native layer.

jamesrogers93 commented 3 months ago

I've just stumbled upon this too! Completely broke functionality in my app as I check for typeof value === 'number'

yuchida0911 commented 2 months ago

if this is an intentional change, I think we should change the interface of the component

maartenschumacher commented 2 months ago

Duplicate of https://github.com/react-native-picker/picker/issues/538