Skip to main content
Version: 3.x

block

block works similarly to requireToFail but the direction of the relation is reversed - instead of being a one-to-many relation, it's many-to-one. It's especially useful for making lists where the ScrollView component needs to wait for every gesture underneath it. All that's required to do is to pass a ref, for example:

function Item({ backgroundColor, scrollGesture }: ItemProps) {
const scale = useSharedValue(1);
const zIndex = useSharedValue(1);

const pinch = usePinchGesture({
onBegin: () => {
zIndex.value = 100;
},
onUpdate: (e) => {
scale.value *= e.scaleChange;
},
onFinalize: () => {
scale.value = withTiming(1, undefined, (finished) => {
if (finished) {
zIndex.value = 1;
}
});
},
block: scrollGesture ?? undefined,
});

const animatedStyles = useAnimatedStyle(() => ({
transform: [{ scale: scale.value }],
zIndex: zIndex.value,
}));

return (
<GestureDetector gesture={pinch}>
<Animated.View
style={[
{ backgroundColor: backgroundColor },
styles.item,
animatedStyles,
]}
/>
</GestureDetector>
);
}

export default function App() {
const [scrollGesture, setScrollGesture] = useState<NativeGesture | null>(
null
);

return (
<GestureHandlerRootView style={styles.container}>
<ScrollView
style={styles.container}
onGestureUpdate_CAN_CAUSE_INFINITE_RERENDER={(gesture) => {
if (
!scrollGesture ||
scrollGesture.handlerTag !== gesture.handlerTag
) {
setScrollGesture(gesture);
}
}}>
{ITEMS.map((item) => (
<Item
backgroundColor={item}
key={item}
scrollGesture={scrollGesture}
/>
))}
</ScrollView>
</GestureHandlerRootView>