Hooks and utilities to simplify scrolling to elements (anchors) in React Native.
- Easy to use 🚀
- Lightweight and fast ⚡️
- Zero dependencies 📦
npm install @sellpy/react-native-scroll-anchor
import React, { useRef } from 'react';
import { Button, ScrollView, TextInput, View } from 'react-native';
import {
Anchor,
ScrollAnchorProvider,
useScrollAnchor,
} from '@sellpy/react-native-scroll-anchor';
export default function App() {
const scrollRef = React.useRef<ScrollView>(null);
const methods = useScrollAnchor(scrollRef);
const { scrollTo, onScroll } = methods;
return (
<ScrollAnchorProvider {...methods}>
<Button onPress={() => scrollTo('books')} title="View books" />
<ScrollView onScroll={onScroll} scrollEventThrottle={32} ref={scrollRef}>
<Anchor name="movies">
<MovieList />
</Anchor>
<Anchor name="books">
<BookList />
</Anchor>
</ScrollView>
</ScrollAnchorProvider>
);
}
The useScrollAnchor
hook is used to register and unregister anchors, scroll to anchors, and listen to scroll events.
import { useScrollAnchor } from '@sellpy/react-native-scroll-anchor';
export function MyComponent() {
const ref = useRef(null);
const { register, unregister, scrollTo, timeoutOnScroll, onScroll } =
useScrollAnchor(ref, {
onAnchorReachedX: (name) =>
console.log('Reached anchor on x-axis:', name),
onAnchorReachedY: (name) =>
console.log('Reached anchor on y-axis:', name),
});
return (
<ScrollView
onScroll={onScroll}
scrollEventThrottle={32}
ref={scrollRef}
></ScrollView>
);
}
Args
Name | Type | Default | Description |
---|---|---|---|
ref | RefObject<ScrollView> |
The ref of the ScrollView component | |
options | ScrollAnchorOptions | {} |
Options |
Returns ScrollAnchorMethods
Another way to register an anchor is by using the useAnchorRef
hook. This hook is useful when you want to register an anchor ref without using the <Anchor/>
component.
This component requires the ScrollAnchorProvider
to be present in the component tree.
import { useAnchorRef } from '@sellpy/react-native-scroll-anchor';
export function MyComponent() {
const ref = useAnchorRef('item');
return (
<View ref={ref}>
<Text>Awesome Item</Text>
</View>
);
Args
Name | Type | Default | Description |
---|---|---|---|
name | string |
The name of the anchor |
Returns RefObject<NativeView>
Sets up a provider enabling usage of <Anchor />
and useAnchorRef
in the component tree.
import {
ScrollAnchorProvider,
useScrollAnchor,
} from '@sellpy/react-native-scroll-anchor';
import { ScrollView } from 'react-native';
export function MyComponent() {
const scrollViewRef = useRef<ScrollView>(null);
const methods = useScrollAnchor(ref);
return (
<ScrollAnchorProvider {...methods}>
<ScrollView
ref={scrollViewRef}
onScroll={methods.onScroll}
scrollEventThrottle={16}
>
<MyAnchoredComponent />
</ScrollView>
</ScrollAnchorProvider>
);
}
Props
Name | Type | Default | Description |
---|---|---|---|
children | ReactNode |
The children to render | |
...methods | ScrollAnchorMethods | Provide all methods returned form useScrollAnchor |
The <Anchor/>
component is used to wrap a component that you want to scroll to.
This component requires the ScrollAnchorProvider
to be present in the component tree.
import { Anchor } from '@sellpy/react-native-scroll-anchor';
<Anchor name="item">
<MyAnchoredComponent />
</Anchor>;
Props
Name | Type | Default | Description |
---|---|---|---|
name | string |
The name of the anchor. You can scroll to this anchor by calling scrollTo() |
interface ScrollAnchorOptions {
/* Throttles onAnchorReachedX, onAnchorReachedY callbacks per anchor name as well as the scrollTo method. The number is in MS */
throttle?: number /* default: 200 (ms) */;
/* Offset for the x-axis when scrolling to an anchor */
offsetX?: number /* default: 0 */;
/* Offset for the y-axis when scrolling to an anchor */
offsetY?: number /* default: 0 */;
/* Callback when an anchor is reached on the x-axis. Requires binding of `onScroll` between referenced `ScrollView` and returned `onScroll` method */
onAnchorReachedX?: (name: string) => void;
/* Callback when an anchor is reached on the y-axis. Same requriements as for onAnchorReachedX */
onAnchorReachedY?: (name: string) => void;
/* If true, we make sure onAnchorReachedX and onAnchorReachedY are called when scrolling. They will be called with the nearest anchor */
keepInBounds?: boolean /* default: false */;
}
interface ScrollAnchorMethods {
/* Register an anchor with a name and a ref. */
register: (name: string, ref: React.RefObject<NativeComponent>) => void;
/* Unregister an anchor by name. */
unregister: (name: string) => void;
/* Scroll to an anchor by name. */
scrollTo: (name: string) => void;
/* Timeout onScroll manually, this won't cause onAnchorReachedX or onAnchorReachedY to be called. */
timeoutOnScroll: (timeMs: number) => void;
/* The onScroll event handler. Pass this to the ScrollView component. **NOTE: this is required for if onScrollAnchorReachedX or onScrollAnchorReachedY should be called.** */
onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
/* The refs of all registered anchors, key is anchor name povided */
anchorRefs: Record<string, React.RefObject<NativeComponent>>;
}
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT