The Android app is crashing when reseting items and value at the same time.
In my app I have 3 dropdown which depend on each other, every time I try change the value from the first, I need to reset the items and value of the 2 others, and when that happen on Android the app crashed right away.
Expected behavior
By clearing the items array and the value, the picker should display the picker without any items.
Smartphone (please complete the following information):
Logs
07-30 17:30:34.390 E unknown ReactNative: Exception in native call
07-30 17:30:34.390 E unknown ReactNative: java.lang.ArrayIndexOutOfBoundsException: length=2; index=2
07-30 17:30:34.390 E unknown ReactNative: at java.util.Arrays$ArrayList.get(Arrays.java:3769)
07-30 17:30:34.390 E unknown ReactNative: at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:393)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.views.picker.ReactPickerManager$ReactPickerAdapter.getView(ReactPickerManager.java:116)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.views.picker.ReactPickerManager$ReactPickerAdapter.getView(ReactPickerManager.java:107)
07-30 17:30:34.390 E unknown ReactNative: at android.widget.Spinner.makeView(Spinner.java:712)
07-30 17:30:34.390 E unknown ReactNative: at android.widget.Spinner.layout(Spinner.java:660)
07-30 17:30:34.390 E unknown ReactNative: at android.widget.AbsSpinner.setSelectionInt(AbsSpinner.java:306)
07-30 17:30:34.390 E unknown ReactNative: at android.widget.AbsSpinner.setSelection(AbsSpinner.java:283)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.views.picker.ReactPicker.commitStagedData(ReactPicker.java:142)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.views.picker.ReactPickerManager.onAfterUpdateTransaction(ReactPickerManager.java:80)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.views.picker.ReactPickerManager.onAfterUpdateTransaction(ReactPickerManager.java:36)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:47)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.uimanager.NativeViewHierarchyManager.updateProperties(NativeViewHierarchyManager.java:139)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.uimanager.UIViewOperationQueue$UpdatePropertiesOperation.execute(UIViewOperationQueue.java:93)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:844)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:952)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.uimanager.UIViewOperationQueue.access$2200(UIViewOperationQueue.java:44)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1012)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:172)
07-30 17:30:34.390 E unknown ReactNative: at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:84)
07-30 17:30:34.390 E unknown ReactNative: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:947)
07-30 17:30:34.390 E unknown ReactNative: at android.view.Choreographer.doCallbacks(Choreographer.java:761)
07-30 17:30:34.390 E unknown ReactNative: at android.view.Choreographer.doFrame(Choreographer.java:693)
07-30 17:30:34.390 E unknown ReactNative: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
07-30 17:30:34.390 E unknown ReactNative: at android.os.Handler.handleCallback(Handler.java:873)
07-30 17:30:34.390 E unknown ReactNative: at android.os.Handler.dispatchMessage(Handler.java:99)
07-30 17:30:34.390 E unknown ReactNative: at android.os.Looper.loop(Looper.java:193)
07-30 17:30:34.390 E unknown ReactNative: at android.app.ActivityThread.main(ActivityThread.java:6669)
07-30 17:30:34.390 E unknown ReactNative: at java.lang.reflect.Method.invoke(Native Method)
07-30 17:30:34.390 E unknown ReactNative: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
07-30 17:30:34.390 E unknown ReactNative: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
07-30 17:30:34.393 D AndroidRuntime Shutting down VM
07-30 17:30:34.393 E AndroidRuntime FATAL EXCEPTION: main
07-30 17:30:34.393 E AndroidRuntime java.lang.ArrayIndexOutOfBoundsException: length=2; index=2
07-30 17:30:34.393 E AndroidRuntime at java.util.Arrays$ArrayList.get(Arrays.java:3769)
07-30 17:30:34.393 E AndroidRuntime at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:393)
07-30 17:30:34.393 E AndroidRuntime at com.facebook.react.views.picker.ReactPickerManager$ReactPickerAdapter.getView(ReactPickerManager.java:116)
07-30 17:30:34.393 E AndroidRuntime at com.facebook.react.views.picker.ReactPickerManager$ReactPickerAdapter.getView(ReactPickerManager.java:107)
07-30 17:30:34.393 E AndroidRuntime at android.widget.Spinner.makeView(Spinner.java:712)
07-30 17:30:34.393 E AndroidRuntime at android.widget.Spinner.layout(Spinner.java:660)
07-30 17:30:34.393 E AndroidRuntime at android.widget.Spinner.onLayout(Spinner.java:622)
07-30 17:30:34.393 E AndroidRuntime at com.facebook.react.views.picker.ReactPicker.onLayout(ReactPicker.java:98)
07-30 17:30:34.393 E AndroidRuntime at android.view.View.layout(View.java:20672)
07-30 17:30:34.393 E AndroidRuntime at android.view.ViewGroup.layout(ViewGroup.java:6194)
07-30 17:30:34.393 E AndroidRuntime at com.facebook.react.views.picker.ReactPicker$2.run(ReactPicker.java:81)
07-30 17:30:34.393 E AndroidRuntime at android.os.Handler.handleCallback(Handler.java:873)
07-30 17:30:34.393 E AndroidRuntime at android.os.Handler.dispatchMessage(Handler.java:99)
07-30 17:30:34.393 E AndroidRuntime at android.os.Looper.loop(Looper.java:193)
07-30 17:30:34.393 E AndroidRuntime at android.app.ActivityThread.main(ActivityThread.java:6669)
07-30 17:30:34.393 E AndroidRuntime at java.lang.reflect.Method.invoke(Native Method)
07-30 17:30:34.393 E AndroidRuntime at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
07-30 17:30:34.393 E AndroidRuntime at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Fill out the entire bug report
I'm also experiencing this on Android rn 0.60.4 only in release bundle

@lfkwtz can this be re-opened? I won't open a new issue/bug since i don't have reproducible steps - we're only seeing this come through our Sentry error reporting randomly without any rhyme or reason. I've attached the screenshot from native stack trace above.
@crobinson42 sure i'll reopen it for a while - maybe someone can share some code that will reproduce this.
Here's my component that uses this lib where the native error is being thrown:
````
import React from 'react'
import PropTypes from 'prop-types'
import { View } from 'react-native'
import { Input } from 'react-native-elements'
import Select from 'react-native-picker-select'
import { useSelector } from 'react-redux'
function DepartmentPicker(props) {
const departments = useSelector(state => state.site.departments)
const handleChange = option => {
if (props.onChange) props.onChange(option)
}
const deptItems = departments.map(({ departmentId, name }) => ({
label: name,
value: departmentId,
}))
const inputValue = (deptItems.find(item => item.value === props.value) || {})
.label
return (
disabled={props.disabled}
items={deptItems}
onValueChange={handleChange}
placeholder={{
label: 'Select Department',
value: null,
}}
value={props.value}
>
editable={false}
placeholder='Department'
rightIcon={{
color: SSCS_GREY_LIGHTENED,
containerStyle: { paddingRight: 10 },
name: 'caretdown',
type: 'antdesign',
}}
inputStyle={props.inputStyle}
value={inputValue}
/>
)
}
```
The problem for us is the items list is dynamic in our component. When we explicitly pass value to react-native-picker-select and the items list is updated from some external user action to a new items list, react-native-picker-select's internal state of the index of the last value is passed to the native react-native picker component of an index that no longer exists in the items list.
@lfkwtz there should be a small change in the underlying logic for the react-native-picker-select component to always verify that the index exists in props.items before passing it to react-native picker to prevent this from happening in the future.
Solved
The problem for us is the
itemslist is dynamic in our component. When we explicitly passvaluetoreact-native-picker-selectand theitemslist is updated from some external user action to a newitemslist,react-native-picker-select's internal state of the index of the last value is passed to the native react-native picker component of an index that no longer exists in theitemslist.@lfkwtz there should be a small change in the underlying logic for the
react-native-picker-selectcomponent to always verify that the index exists inprops.itemsbefore passing it to react-native picker to prevent this from happening in the future.
That's exactly the same thing that was happening for me, but I was looking at react-native-picker-select code to see how they deal with this, and it seems to be handling it correctly, so I think it might be related with the way RN Android Picker handles items changes itself.
did this issue just crop up recently for either of you after updating RN? since you're both on 0.60.4 and I haven't seen this bug before...
I only recently started using this lib. We haven’t experienced the same issue in the last 2 years before when we used the native component.
Sent from my iPhone
On Aug 6, 2019, at 11:06 AM, Michael Lefkowitz notifications@github.com wrote:
did this issue just crop up recently for either of you after updating RN? since you're both on 0.60.4 and I haven't seen this bug before...
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
@lfkwtz In my case, I've been using this library for over a year, and never had this issue before. I didn't notice it when I first did the RN upgrade to 0.60.0, because it doesn't crash right away, you have to be updating the picker in order for it to crash on Android. iOS has worked for me just fine. Noticed on 0.60.4, because is where an actual user reported it, so I did the research about it and found this.
I was able to consistently reproduce this with 2 picker components on a screen at the same time where PickerA's selected item determines PickerB's items to render.
When PickerB has a selected item who's item's list index is say 10, then PickerA's selected item is changed and PickerB's items prop is changed and does not contain an index of 10, the ArrayIndexOutOfBoundsException will throw in the native code.
High level (opinion) this component should be refactored to get rid of getDerivedStateFromProps() because the current logic/order is causing the selectedValue passed to the react-native Picker component to get out of sync with the items list from props that are passed in. In other words, when this components items list is updated, they are rendered and passed to react-native's Picker component with selectedValue of the previous items list in the last render.
Cool - will check out the pr soon. The eventual plan is to split off into named exports so I can make this a controlled component to fix #112 and in general make the component a little more dumb - but still have the 'legacy' export too. But in the near term, having some additional checks in there to prevent bugs like this is fine with me.
Someone on my team found another solution to this problem - you can pass key={items.length} to this component which will causes it to remount on render when the items.length changes.
Workaround Solution
Someone on my team found another solution to this problem - you can pass
key={items.length}to this component which will causes it to remount on render when the items.length changes.
it works, thank you
i'm going to close this out since it is an upstream issue https://github.com/facebook/react-native/issues/26406
Most helpful comment
Workaround Solution
Someone on my team found another solution to this problem - you can pass
key={items.length}to this component which will causes it to remount on render when the items.length changes.