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)
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.
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.
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.