@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
56 lines (47 loc) • 1.4 kB
text/typescript
import * as React from "react";
const layoutReducer = (state, { payload }) => {
return state.map((item, index, _state) => ({
height: index === payload.index ? payload.height : item.height,
y:
index > 0
? _state.slice(0, index).reduce((acc, value) => acc + value.height, 0)
: 0,
}));
};
export const useComponentsLayout = (count, onFinishLoadingVisible) => {
const [itemsLayout, dispatchItemLayout] = React.useReducer(
layoutReducer,
Array.from({ length: count }, () => ({ height: 0, y: 0 }))
);
const notified = React.useRef(false);
const [listHeight, setListHeight] = React.useState<number>(0);
const onItemLayout = React.useCallback(
(index) => (event) => {
const { height } = event.nativeEvent.layout;
dispatchItemLayout({ payload: { index, height } });
},
[]
);
const onListLayout = React.useCallback((event) => {
const { height } = event.nativeEvent.layout;
setListHeight(height);
}, []);
React.useEffect(() => {
if (!notified.current) {
const finishLoadingVisible = !!itemsLayout.find(
(item) => item.y > listHeight
);
if (finishLoadingVisible) {
notified.current = true;
onFinishLoadingVisible?.();
}
}
}, [itemsLayout, listHeight]);
return React.useMemo(
() => ({
onItemLayout,
onListLayout,
}),
[]
);
};