Skip to content

Commit

Permalink
fix: remove eventemitter dependency, replace batcher with requestanim…
Browse files Browse the repository at this point in the history
…ationframe
  • Loading branch information
azimgd committed May 23, 2024
1 parent a057801 commit 3474797
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 62 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ It invokes Yoga for precise layout measurements of Shadow Nodes and constructs a
| 60 FPS Scrolling |||
| No Content Flashing |||
| No Sidebar Indicator Jump |||
| Maintain Content Position |||
| Fast initialScrollIndex |||
| Bi-directional Scrolling |||
| Nested ShadowList (ScrollView) |||
| Natively Inverted List Support |||
| Smooth Scrolling |||
Expand Down
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,5 @@
"name": "RNShadowListContainerSpec",
"type": "components",
"jsSrcsDir": "src"
},
"dependencies": {
"eventemitter3": "^5.0.1"
}
}
66 changes: 17 additions & 49 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import React from 'react';
import {
StyleSheet,
type ViewStyle,
type NativeSyntheticEvent,
} from 'react-native';
import EventEmitter from 'eventemitter3';
import { StyleSheet, type ViewStyle } from 'react-native';
import ShadowListContainerNativeComponent, {
Commands,
type NativeProps,
type NativeCommands,
type OnBatchLayoutProps,
} from './ShadowListContainerNativeComponent';
import ShadowListItemNativeComponent from './ShadowListItemNativeComponent';

const emitter = new EventEmitter();
const BATCHER_SIZE = 50;

type Component =
| React.ComponentType<any>
| React.ReactElement
Expand Down Expand Up @@ -58,38 +49,27 @@ export type ShadowListItemWrapperProps = {
item: any;
};

/**
* Primitive batcher implementation
*/
const useBatcher = (index: number) => {
const [isReady, setIsReady] = React.useState(false);

React.useEffect(() => {
const animationFrame = requestAnimationFrame(() => setIsReady(true));
return () => cancelAnimationFrame(animationFrame);
}, [index]);

return isReady;
};

const ShadowListItemWrapper = ({
item,
renderItem,
index,
}: ShadowListItemWrapperProps) => {
/**
* Always layout this component if it is within the first BATCHER_SIZE items.
*/
const [isReady, setIsReady] = React.useState(index < BATCHER_SIZE);

/**
* Listens for the 'onBatchLayout' event.
* Sets the component to ready when its index is within the batch layout meaning that it's layed out.
*/
React.useEffect(() => {
const listener = (batchLayoutSize: number) => {
const shouldRenderListItem = index <= batchLayoutSize + BATCHER_SIZE;
if (!shouldRenderListItem) return;
emitter.off('onBatchLayout', listener);
setIsReady(true);
};

emitter.on('onBatchLayout', listener);

return () => {
emitter.off('onBatchLayout', listener);
};
}, [index]);

if (!isReady) {
return null;
}
const isReady = useBatcher(index);
if (!isReady) return;

return (
<ShadowListItemNativeComponent key={index}>
Expand Down Expand Up @@ -191,25 +171,13 @@ const ShadowListContainerWrapper = (
[data, props.renderItem, props.inverted]
);

/**
* Notifies all subscribed components about a new layout batch size.
* It uses an event notifier to reduce re-renders of the parent list component.
*/
const handleBatchLayout = React.useCallback(
(event: NativeSyntheticEvent<OnBatchLayoutProps>) => {
emitter.emit('onBatchLayout', event.nativeEvent.size);
},
[]
);

return (
<ShadowListContainerNativeComponent
{...props}
ref={instanceRef}
hasListHeaderComponent={!!props.ListHeaderComponent}
hasListFooterComponent={!!props.ListFooterComponent}
style={[props.contentContainerStyle, baseStyle]}
onBatchLayout={handleBatchLayout}
>
{!props.inverted ? ListHeaderComponent : ListFooterComponent}
{data.length ? ListChildrenComponent : ListEmptyComponent}
Expand Down
8 changes: 0 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6177,13 +6177,6 @@ __metadata:
languageName: node
linkType: hard

"eventemitter3@npm:^5.0.1":
version: 5.0.1
resolution: "eventemitter3@npm:5.0.1"
checksum: 543d6c858ab699303c3c32e0f0f47fc64d360bf73c3daf0ac0b5079710e340d6fe9f15487f94e66c629f5f82cd1a8678d692f3dbb6f6fcd1190e1b97fcad36f8
languageName: node
linkType: hard

"execa@npm:7.1.1":
version: 7.1.1
resolution: "execa@npm:7.1.1"
Expand Down Expand Up @@ -11770,7 +11763,6 @@ __metadata:
eslint: ^8.51.0
eslint-config-prettier: ^9.0.0
eslint-plugin-prettier: ^5.0.1
eventemitter3: ^5.0.1
jest: ^29.7.0
prettier: ^3.0.3
react: 18.2.0
Expand Down

0 comments on commit 3474797

Please sign in to comment.