Skip to content

Commit 1609a1e

Browse files
committed
add stable callback, fix calling setPage on mount
1 parent a24fa83 commit 1609a1e

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

src/index.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, {
22
useState,
33
useImperativeHandle,
4-
useCallback,
54
useRef,
65
useContext,
76
useMemo,
@@ -33,6 +32,7 @@ import {
3332
pageInterpolatorStack,
3433
pageInterpolatorTurnIn,
3534
} from "./pageInterpolators";
35+
import { useStableCallback } from "./useStableCallback";
3636

3737
export enum Preset {
3838
SLIDE = "slide",
@@ -147,6 +147,13 @@ function InfinitePager(
147147
const pageHeight = useSharedValue(height || 0);
148148
const pageSize = vertical ? pageHeight : pageWidth;
149149

150+
const onLayoutResolveRef = useRef((_val: number) => {});
151+
const onLayoutPromiseRef = useRef(
152+
new Promise<number>((resolve) => {
153+
onLayoutResolveRef.current = resolve;
154+
})
155+
);
156+
150157
const translateX = useSharedValue(0);
151158
const translateY = useSharedValue(0);
152159
const translate = vertical ? translateY : translateX;
@@ -189,9 +196,11 @@ function InfinitePager(
189196
return !!gesturesDisabled;
190197
}, [gesturesDisabled]);
191198

192-
const setPage = useCallback(
193-
(index: number, options: ImperativeApiOptions = {}) => {
194-
const updatedTranslate = index * pageSize.value * -1;
199+
const setPage = useStableCallback(
200+
async (index: number, options: ImperativeApiOptions = {}) => {
201+
const layoutPageSize = await onLayoutPromiseRef.current;
202+
const pSize = pageSize.value || layoutPageSize;
203+
const updatedTranslate = index * pSize * -1;
195204

196205
if (index < minIndex || index > maxIndex) return;
197206

@@ -205,8 +214,7 @@ function InfinitePager(
205214
} else {
206215
translate.value = updatedTranslate;
207216
}
208-
},
209-
[pageSize, translate, minIndex, maxIndex]
217+
}
210218
);
211219

212220
useImperativeHandle(
@@ -234,10 +242,10 @@ function InfinitePager(
234242
}
235243
}, [pageSize, pageAnim, translate]);
236244

237-
function onPageChangeInternal(pg: number) {
245+
const onPageChangeInternal = useStableCallback((pg: number) => {
238246
onPageChange?.(pg);
239247
setCurIndex(pg);
240-
}
248+
});
241249

242250
useAnimatedReaction(
243251
() => {
@@ -455,6 +463,7 @@ function InfinitePager(
455463
onLayout={({ nativeEvent: { layout } }) => {
456464
pageWidth.value = layout.width;
457465
pageHeight.value = layout.height;
466+
onLayoutResolveRef.current(vertical ? layout.height : layout.width);
458467
}}
459468
>
460469
{pageIndices.map((pageIndex) => {

src/useStableCallback.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Utility hook that returns a function that never has stale dependencies, but
2+
// without changing identity, as a useCallback with dep array would.
3+
// Useful for functions that depend on external state, but
4+
// should not trigger effects when that external state changes.
5+
6+
import { useCallback, useRef } from "react";
7+
8+
export function useStableCallback<
9+
T extends (arg1?: any, arg2?: any, arg3?: any) => any
10+
>(cb: T) {
11+
const cbRef = useRef(cb);
12+
cbRef.current = cb;
13+
const stableCb = useCallback(
14+
(...args: Parameters<T>) => cbRef.current(...args),
15+
[]
16+
);
17+
return stableCb as T;
18+
}

0 commit comments

Comments
 (0)