Programmatic Control
Learn how to control the carousel programmatically using imperative methods via refs.
Note: This library doesn't support React-style controlled components (with an index
prop). Instead, it uses an imperative API via refs for programmatic control.
Overview
The carousel provides several methods to control its behavior programmatically:
scrollTo
- Scroll to a specific index or relative positionnext
- Move to the next item(s)prev
- Move to the previous item(s)getCurrentIndex
- Get the current active index
Basic Setup
First, create a ref and attach it to the carousel:
import React, { useRef } from 'react';
import Carousel, { ICarouselInstance } from 'react-native-reanimated-carousel';
function MyCarousel() {
const carouselRef = useRef<ICarouselInstance>(null);
return (
<Carousel
ref={carouselRef}
// ... other props
/>
);
}
Methods
scrollTo
The most versatile method for controlling carousel navigation.
Scroll to specific index
// Jump to index 3 with animation
carouselRef.current?.scrollTo({
index: 3,
animated: true
});
// Jump to index 0 without animation
carouselRef.current?.scrollTo({
index: 0,
animated: false
});
Scroll relative to current position
// Move 2 items forward (equivalent to calling next twice)
carouselRef.current?.scrollTo({
count: 2,
animated: true
});
// Move 1 item backward (equivalent to calling prev once)
carouselRef.current?.scrollTo({
count: -1,
animated: true
});
With callback
carouselRef.current?.scrollTo({
index: 2,
animated: true,
onFinished: () => {
console.log('Scroll completed!');
}
});
next & prev
Simplified methods for moving forward or backward:
// Move to next item
carouselRef.current?.next({ animated: true });
// Move 3 items forward
carouselRef.current?.next({
count: 3,
animated: true
});
// Move to previous item
carouselRef.current?.prev({ animated: true });
// Move 2 items backward
carouselRef.current?.prev({
count: 2,
animated: false
});
getCurrentIndex
Get the current active index:
const currentIndex = carouselRef.current?.getCurrentIndex();
console.log('Current index:', currentIndex);
Practical Examples
Pagination Control
import React, { useRef } from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
import { useSharedValue } from 'react-native-reanimated';
import Carousel, { ICarouselInstance, Pagination } from 'react-native-reanimated-carousel';
function CarouselWithPagination() {
const carouselRef = useRef<ICarouselInstance>(null);
const progress = useSharedValue<number>(0);
const data = [...new Array(5).keys()];
const onPressPagination = (index: number) => {
carouselRef.current?.scrollTo({
count: index - progress.value,
animated: true,
});
};
return (
<View>
<Carousel
ref={carouselRef}
data={data}
onProgressChange={progress}
// ... other props
/>
<Pagination.Basic
progress={progress}
data={data}
onPress={onPressPagination}
/>
</View>
);
}
Navigation Buttons
function CarouselWithButtons() {
const carouselRef = useRef<ICarouselInstance>(null);
return (
<View>
<Carousel
ref={carouselRef}
// ... props
/>
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
<TouchableOpacity
onPress={() => carouselRef.current?.prev({ animated: true })}
>
<Text>Previous</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => carouselRef.current?.next({ animated: true })}
>
<Text>Next</Text>
</TouchableOpacity>
</View>
</View>
);
}
Dynamic Content Updates
When updating data and needing to scroll to new items:
function DynamicCarousel() {
const carouselRef = useRef<ICarouselInstance>(null);
const [items, setItems] = useState(initialItems);
const addItemAndNavigate = (newItem) => {
const newItems = [...items, newItem];
setItems(newItems);
// Wait for next render cycle before scrolling
setTimeout(() => {
carouselRef.current?.scrollTo({
index: newItems.length - 1,
animated: true
});
}, 0);
};
// Alternative: Use useEffect to handle timing
useEffect(() => {
if (items.length > initialItems.length) {
// Scroll to the last item when new items are added
carouselRef.current?.scrollTo({
index: items.length - 1,
animated: true
});
}
}, [items]);
return (
<Carousel
ref={carouselRef}
data={items}
// ... other props
/>
);
}
Common Patterns
Auto-advance Carousel
function AutoAdvanceCarousel() {
const carouselRef = useRef<ICarouselInstance>(null);
const [currentIndex, setCurrentIndex] = useState(0);
const data = [...new Array(5).keys()];
useEffect(() => {
const timer = setInterval(() => {
const nextIndex = (currentIndex + 1) % data.length;
carouselRef.current?.scrollTo({
index: nextIndex,
animated: true
});
setCurrentIndex(nextIndex);
}, 3000);
return () => clearInterval(timer);
}, [currentIndex, data.length]);
return (
<Carousel
ref={carouselRef}
data={data}
// ... other props
/>
);
}
Jump to Item by ID
function SearchableCarousel() {
const carouselRef = useRef<ICarouselInstance>(null);
const data = [
{ id: 'item1', title: 'Item 1' },
{ id: 'item2', title: 'Item 2' },
{ id: 'item3', title: 'Item 3' },
];
const jumpToItemById = (itemId: string) => {
const index = data.findIndex(item => item.id === itemId);
if (index !== -1) {
carouselRef.current?.scrollTo({
index,
animated: true
});
}
};
return (
<View>
<Carousel
ref={carouselRef}
data={data}
// ... other props
/>
<TouchableOpacity onPress={() => jumpToItemById('item2')}>
<Text>Jump to Item 2</Text>
</TouchableOpacity>
</View>
);
}
Important Notes
Race Condition Warning: When updating data and immediately calling scroll methods, you might encounter race conditions. The carousel may not have rendered the new data yet. Use setTimeout
or useEffect
to ensure proper timing.
No Controlled Component Pattern: Unlike typical React components, this carousel doesn't support controlled mode via props (like currentIndex={index}
). All programmatic control must be done through the imperative ref API.
API Reference
scrollTo Options
Property | Type | Default | Description |
---|---|---|---|
index | number | - | Target index to scroll to |
count | number | - | Relative position change (positive = forward, negative = backward) |
animated | boolean | true | Whether to animate the scroll |
onFinished | () => void | - | Callback when scroll completes |
next/prev Options
Property | Type | Default | Description |
---|---|---|---|
count | number | 1 | Number of items to advance |
animated | boolean | true | Whether to animate the scroll |
onFinished | () => void | - | Callback when scroll completes |
This imperative approach gives you full control over the carousel's navigation while maintaining smooth animations and proper state management.