Synchronizing Scroll Views
In this lesson, you will learn how to link two separate scrollable containers so that when a user scrolls through one, the other follows along in perfect harmony.
The Concept
Imagine you are building a dashboard with a side-by-side view: a list of labels on the left and a detailed data table on the right. To keep the content aligned, you need to ensure that the vertical scroll position of the first ScrollView is mirrored by the second.
In React Native, we achieve this by using the onScroll prop to capture the offset of the primary list, and then using a ref on the secondary list to force it to jump to that same position using scrollTo().
Implementation
To prevent an infinite loop where the second view triggers the first, we keep track of the scroll offset in state or a ref. Here is a simplified pattern:
const scrollRef1 = useRef(null);
const scrollRef2 = useRef(null);
const handleScroll = (event) => {
const yOffset = event.nativeEvent.contentOffset.y;
// Programmatically scroll the second view to match the first
scrollRef2.current?.scrollTo({ y: yOffset, animated: false });
};
return (
<View style={{ flexDirection: 'row' }}>
<ScrollView
ref={scrollRef1}
onScroll={handleScroll}
scrollEventThrottle={16} // Ensures smooth sync
>
{/* Content A */}
</ScrollView>
<ScrollView ref={scrollRef2} scrollEnabled={false}>
{/* Content B */}
</ScrollView>
</View>
);
Why This Matters
By setting scrollEventThrottle={16}, we tell React Native to fire the scroll event approximately every 16 milliseconds (matching the 60fps refresh rate). This makes the synchronization feel seamless to the user. While we often disable scrolling on the "follower" view using scrollEnabled={false} to keep the gesture restricted to the main list, this technique ensures your complex, multi-column layouts always stay perfectly aligned.
Key Takeaway: You can synchronize ScrollViews by capturing the scroll event offset of a leader component and applying that value to a follower component using the scrollTo method via refs.