Rethinking the "Compat" abstraction (types/reanimated issue)
See original GitHub issueThe RecyclerListView
component is rather exotic in the react ecosystem, since it does not directly derive from/extend ComponentType<P, S, SS>
. Instead, it derives from/extends ComponentCompat<T1, T2, SS>
, which itself extends from React.Component<T1, T2, SS>
. While this works fine at runtime, it doesn’t work when trying to create HoCs or “wrappers” for the RecyclerListView
component.
An example for this would be the createAnimatedComponent
function from react-native-reanimated, which enables all props and style-props to be animated values/shared values. To maintain type-safety for this function, it is expected to receive a parameter of type ComponentType<P>
, which doesn’t match the RecyclerListView
’s type causing the following TypeScript errors:
src/screens/main/home/HomeScreen.tsx:45:71 - error TS2345: Argument of type 'typeof RecyclerListView' is not assignable to parameter of type 'ComponentType<{ style?: StyleProp<object>; }>'.
Type 'typeof RecyclerListView' is not assignable to type 'ComponentClass<{ style?: StyleProp<object>; }, any>'.
Types of property 'defaultProps' are incompatible.
Type '{ canChangeSize: boolean; disableRecycling: boolean; initialOffset: number; initialRenderIndex: number; isHorizontal: boolean; onEndReachedThreshold: number; renderAheadOffset: number; }' has no properties in common with type 'Partial<{ style?: StyleProp<object>; }>'.
45 const ReanimatedRecyclerListView = Reanimated.createAnimatedComponent(RecyclerListView);
~~~~~~~~~~~~~~~~
src/screens/main/home/HomeScreen.tsx:408:11 - error TS2322: Type '{ style: { marginTop: number; flex: number; }; rowRenderer: (type: unknown, data: Post | "ad") => Element | null; dataProvider: DataProvider; layoutProvider: LayoutProvider; ... 5 more ...; scrollEventThrottle: number; }' is not assignable to type 'IntrinsicAttributes & AnimateProps<object, { style?: StyleProp<object>; }> & { children?: ReactNode; }'.
Property 'rowRenderer' does not exist on type 'IntrinsicAttributes & AnimateProps<object, { style?: StyleProp<object>; }> & { children?: ReactNode; }'.
408 rowRenderer={rowRenderer}
~~~~~~~~~~~
In other words: Animated.createAnimatedComponent(RecyclerListView)
does not work with TypeScript, so we can’t run animations using the onScroll
event. (meaning we have “compile”-time errors and no type safety.)
This issue should be a discussion point if we can do something about this in the RecyclerListView types, or if this has to be ignored and casted to unknown
, causing all type-safety to be lost. Do we even need the ComponentCompat.ts
anymore? Looks like it’s not doing anything specific…
Issue Analytics
- State:
- Created 3 years ago
- Comments:6
Top GitHub Comments
@nandorojo I’ve experimented with it for
react-native-calendar
and had working prototype. Unfortunately, that code was not saved somewhere.I had not seen any performance benefits and, probably, it was even worse than
FlatList
. At least didn’t solve performance issues. So I switched back to just usingFlatList
, trying to squeeze maximum out of it.As far as I remember I couldn’t not make it working purely on UI. Probably I used
renderScrollComponent
to provideAnimated.ScrollView
. Then I usedonScroll
on thatAnimated.ScrollView
to calculate / run animations on UI / etc.And you have to report scroll changes back to
RecyclerListView
, otherwise it wouldn’t know about changes happening. So finally I had to callrunOnJS()
. Probably it ruined the overall idea and performance. Or, at least, I didn’t get what expected.@nandorojo Hello ✋🏻 Do you still need interpolating list item style based on the scroll position?