react-native-reanimated: Exception when unmounting component with Animated Views

Description

I refactored and added confetti animations to React Native “Make It Rain”. It creates 100 nodes by default, but the user can specify more through props. The component throws an exception in some cases, or logs a warning in other cases.

What is the recommended way to clean up nodes to avoid issues? I couldn’t find mention of that in the docs at https://software-mansion.github.io/react-native-reanimated. It calls stopClock() on unmount. I’ve experimented with additional guards in the useCode hook to prevent the clock from restarting, and returning an empty block on unmount.

Screenshots

Steps To Reproduce

Start the example project in the Make It Rain repo. https://github.com/peacechen/react-native-make-it-rain#sample-application

Toggle the switch from Arrive to Rain.

Expected behavior

No errors or warnings. Switch should take effect immediately, but the animations continue to run for 8+ seconds.

Actual behavior

The example project spews Excessive number of pending callbacks: 501 when the animation type is switched. Another user has observed an exception when the component unmounts:

*** Assertion failure in -[REANodesManager disconnectNodes:childID:](), <path-to-project>/node_modules/react-native-reanimated/ios/REANodesManager.m:286

[error][tid:main][RCTUIManager.m:1166] Exception thrown while executing UI block: 'childNode' is a required parameter

Snack or minimal code example

Code is available in the example project and the root of the repo. https://github.com/peacechen/react-native-make-it-rain/tree/master/Example

Package versions

  • React: 16.9.0
  • React Native: 0.61.4
  • React Native Reanimated: 1.8.0

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 15 (9 by maintainers)

Most upvoted comments

The demo app in the OP triggers the error even when the number of nodes is reduced to ~50. I forget the exact number, but I tested with fewer nodes than that and it still caused the unexpected callbacks error.

If you’re saying about this then there’s 50 nodes per one item if I understand code correctly. Even with 10 animated items that’s quite a lot of nodes.

Do the pending callbacks map 1:1 with number of nodes?

Not really, but with a high number of nodes, it’s a good approximation — basically, React Native keeps a queue of callbacks that should be dispatched to JS. If you overflow this queue you’ll get this warning.

How certain are you that Reanimated v2 doesn’t have these types of bugs with high number of nodes? Having been burned once refactoring to Reanimated v1, I’m wary of going through that again.

Because Reanimated 2 doesn’t use nodes at all — we’re using JSI’s shared references. You create so-called ‘worklets’ which are JS functions with annotation. You can also create SharedValues to share data between JS and the native side (asynchronously). Worklets are registered as turbo module functions and because arguments passed are copied (if they’re not shared values) you don’t have any traffic on the bridge. Additionally, worklets are executed on the thread pool, so they don’t block UI thread if they’re executing some heavy code not related to the rendering.

I understand your frustration and as I said, you can create a patch to the reanimated, disabling this node update behavior, and use patch-package to apply it automatically.