1- import { cloneElement , createElement , forwardRef , isValidElement } from 'react' ;
1+ import {
2+ cloneElement ,
3+ createElement ,
4+ forwardRef ,
5+ isValidElement ,
6+ type ComponentType ,
7+ } from 'react' ;
28import { StyleSheet , View , type LayoutChangeEvent } from 'react-native' ;
39import Animated , {
410 Extrapolation ,
@@ -21,6 +27,48 @@ import {
2127import { nativeStyles , scrollShadowStyles } from './scroll-shadow.styles' ;
2228import type { ScrollShadowProps } from './scroll-shadow.types' ;
2329
30+ /**
31+ * Cache for animated components to prevent remounting on every render.
32+ * Using WeakMap ensures components are garbage collected when no longer referenced.
33+ */
34+ const animatedComponentCache = new WeakMap <
35+ ComponentType < any > ,
36+ ComponentType < any >
37+ > ( ) ;
38+
39+ /**
40+ * Gets or creates a cached animated component for the given component type.
41+ * This prevents creating new component types on every render, which would cause
42+ * React to treat them as different components and trigger unmount/remount cycles.
43+ *
44+ * @param ComponentType - The original component type to create an animated version of
45+ * @returns The cached animated component type
46+ * @throws If ComponentType is not a valid component type or if Animated.createAnimatedComponent fails
47+ */
48+ function getAnimatedComponent (
49+ ComponentType : ComponentType < any >
50+ ) : ComponentType < any > {
51+ // Validate that ComponentType is actually a function/component
52+ if ( typeof ComponentType !== 'function' ) {
53+ throw new Error (
54+ 'ScrollShadow: children.type must be a valid React component type'
55+ ) ;
56+ }
57+
58+ let cached = animatedComponentCache . get ( ComponentType ) ;
59+ if ( ! cached ) {
60+ try {
61+ cached = Animated . createAnimatedComponent ( ComponentType ) ;
62+ animatedComponentCache . set ( ComponentType , cached ) ;
63+ } catch ( error ) {
64+ throw new Error (
65+ `ScrollShadow: Failed to create animated component: ${ error instanceof Error ? error . message : String ( error ) } `
66+ ) ;
67+ }
68+ }
69+ return cached ;
70+ }
71+
2472const ScrollShadowRoot = forwardRef < View , ScrollShadowProps > ( ( props , ref ) => {
2573 const {
2674 children,
@@ -144,7 +192,7 @@ const ScrollShadowRoot = forwardRef<View, ScrollShadowProps>((props, ref) => {
144192 scrollEventThrottle,
145193 onScroll,
146194 } )
147- : createElement ( Animated . createAnimatedComponent ( children . type as any ) , {
195+ : createElement ( getAnimatedComponent ( children . type as any ) , {
148196 ...( children as any ) . props ,
149197 onContentSizeChange,
150198 onLayout,
0 commit comments