Shopify / flash-list

A better list for React Native
https://shopify.github.io/flash-list/
MIT License
5.36k stars 276 forks source link

Android app crashes with: IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. #1241

Open finsterwalder opened 2 months ago

finsterwalder commented 2 months ago

Current behavior

The app crashes on Android, when the list is populated.

IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

android.view.ViewGroup in addViewInner at line 5509 android.view.ViewGroup in addView at line 5328 com.facebook.react.views.view.ReactViewGroup in addView at line 514 android.view.ViewGroup in addView at line 5268 com.facebook.react.views.view.ReactClippingViewManager in addView at line 38 com.facebook.react.views.view.ReactClippingViewManager in addView at line 19 com.facebook.react.uimanager.NativeViewHierarchyManager in manageChildren at line 533 com.swmansion.reanimated.layoutReanimation.ReanimatedNativeHierarchyManager in manageChildren at line 300 com.facebook.react.uimanager.UIViewOperationQueue$ManageChildrenOperation in execute at line 217 com.facebook.react.uimanager.UIViewOperationQueue$1 in run at line 926 com.facebook.react.uimanager.UIViewOperationQueue in flushPendingBatches at line 1037 com.facebook.react.uimanager.UIViewOperationQueue in -$$Nest$mflushPendingBatches com.facebook.react.uimanager.UIViewOperationQueue$2 in runGuarded at line 995 com.facebook.react.bridge.GuardedRunnable in run at line 29 android.os.Handler in handleCallback at line 958 android.os.Handler in dispatchMessage at line 99 android.os.Looper in loopOnce at line 230 android.os.Looper in loop at line 319 android.app.ActivityThread in main at line 8919 java.lang.reflect.Method in invoke com.android.internal.os.RuntimeInit$MethodAndArgsCaller in run at line 578 com.android.internal.os.ZygoteInit in main at line 1103

Unfortunately it's really hard to track why this is happening and I don't have a simple example at hand.

Expected behavior

No crash

To Reproduce

Platform:

Environment

flash-list: 1.6.4 expo: 50 react-native: 0.73.6 react-native-reanimated: 3.6.2

finsterwalder commented 2 months ago

Looking into it a little more I have some more information about how we use the flash-list. The data we give into the list is the value of a Jotai atom "A" that contains an array with Jotai Atoms. I'm not 100% sure, but I think it happens, when we prior removed an item from the list. But maybe it also happens without this. What we definitely do is, we add a new atom the the array underlying the Jotai atom "A".

Cosmin-Madalin commented 1 month ago

@finsterwalder Are you using LayoutAnimation?

finsterwalder commented 1 month ago

Yes, there is some LayoutAnimation in there. We have a surrounding component that calls the following function inside a useLayoutEffect:

const layoutAnimConfig: LayoutAnimationConfig = {
  duration: 300,
  create: {
    duration: 200,
    type: LayoutAnimation.Types.easeInEaseOut,
    property: LayoutAnimation.Properties.opacity,
  },
  update: {
    type: LayoutAnimation.Types.easeInEaseOut,
  },
  delete: {
    duration: 200,
    type: LayoutAnimation.Types.easeInEaseOut,
    property: LayoutAnimation.Properties.opacity,
  },
}

export const updateLayoutAnimation = () => LayoutAnimation.configureNext(layoutAnimConfig)
Cosmin-Madalin commented 1 month ago

You can try without. It is experimental on Android