meliorence / meliorence/react-native-snap-carousel
onBeforeSnapToItem not working properly
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 10.5k
- Forks
- 2.3k
- PR merge metrics
- No merged PRs in 30d
Description
Hey, I am using this package in my app, but when I am dragging from one item to another onBeforeSnapToItem called on every scroll, it gives me only one index (1) every time.
Code:
import React, { Component, useState } from 'react';
import {
View,
StyleSheet,
Image,
Dimensions,
TouchableOpacity,
Text,
Animated,
FlatList,
TouchableWithoutFeedback,
ActivityIndicator
} from 'react-native';
import styled from 'styled-components/native';
import BottomTabBar from '../components/BottomNavigation';
import BuzzFeed from '../components/BuzzFeed';
import CategoryTab from '../components/CategoryTab';
import { useSelector, useDispatch } from 'react-redux';
import R from '../res/R';
import StoryBoard from '../components/Story/StoryBoard';
import ApiHelper from '../controllers/ApiHelper';
import { fillCategories, fillArticles } from '../store/actions';
import Carousel from 'react-native-snap-carousel';
const Dashboard = (props) => {
let categories = useSelector(state => state.category);
let [currentPaggingIndex, setCurrentPaggingIndex] = useState(0);
const dispatcher = useDispatch();
categories = [{
"category_id": "mix_bag",
"category_name": "Mix Bag",
"category_image": "http://www.gothru.in/uploads/2019061717313125-CATEGORY-8.jpg"
}, ...categories]
const allStories = useSelector(state => state.article);
let [currentArticles, setCurrentArticles] = useState(allStories)
const [currentCategory, setCurrentCategory] = useState(categories[0].category_id);
const [screenToShow, setScreenToShow] = useState(2);
const [isLoading, setIsLoading] = useState(false);
const handleCategoryChange = async (item) => {
setCurrentCategory(item.category_id);
setIsLoading(true);
let resArticles;
if (item.category_id === "mix_bag") {
resArticles = await ApiHelper.getArticle();
} else {
resArticles = await ApiHelper.getArticle(item.category_id);
}
if (resArticles) {
const articles = resArticles.data.article_list;
dispatcher(fillArticles(articles));
setIsLoading(false);
}
}
const renderItem = ({ item }) => (
<TouchableWithoutFeedback>
<StoryBoard type="category" navigate={props.navigate} stories={stories} category={item} />
</TouchableWithoutFeedback>
);
const renderTabItem = ({ item }) => (
<TouchableOpacity onPress={() => handleCategoryChange(item)}>
<View style={currentCategory === item.category_id ? styles.tabItemSelected : styles.tabItem}>
<TabMenuText>{item.category_name}</TabMenuText>
</View>
</TouchableOpacity>
);
const renderStoryBoard = ({ item, index }) => (
<View style={{
flex: 1,
width: R.dimens.screenWidth,
alignContent: "center",
justifyContent: "center",
alignItems: "center",
alignSelf: "center"
}}>
<StoryBoard type="category" category={currentCategory} navigate={props.navigation} stories={currentArticles} />
</View>
);
// onViewableItemsChanged = async ({ viewableItems, changed }) => {
// const { item } = changed[0];
// console.log(viewableItems)
// console.log('MY ITEM IS : ', item);
// if (item.category_id !== "mix_bag") {
// setCurrentCategory(changed[0].item.category_id)
// setIsLoading(true);
// let resArticles;
// if (item.category_id === "mix_bag") {
// resArticles = await ApiHelper.getArticle();
// } else {
// resArticles = await ApiHelper.getArticle(item.category_id);
// }
// if (resArticles) {
// const articles = resArticles.data.article_list;
// dispatcher(fillArticles(articles));
// setIsLoading(false);
// }
// }
// }
const onScrollEnd = async (category) => {
let resArticles;
console.log(category);
if (category === "mix_bag") {
resArticles = await ApiHelper.getArticle();
} else {
resArticles = await ApiHelper.getArticle(category);
}
if (resArticles) {
const articles = resArticles.data.article_list;
dispatcher(fillArticles(articles));
setIsLoading(false);
}
}
return (
<Container style={styles.container}>
<View>
{/* Header Logo */}
<HeaderImage
style={styles.header_logo}
source={R.images.header_logo}
/>
{/* Preference Button */}
<TouchableOpacity
style={{ position: 'absolute', alignSelf: 'flex-start' }}
onPress={() => props.navigation.navigate('Preferences')}>
<Prefrences
style={styles.prefrences}
source={R.images.prefrences}
/>
</TouchableOpacity>
</View>
<View style={{ marginTop: 10 }}></View>
{/* Category Tab */}
<View styles={styles.tabBar}>
<Animated.FlatList
data={categories}
keyExtractor={item => item.category_id}
renderItem={renderTabItem}
horizontal
showsHorizontalScrollIndicator={false}
/>
</View>
{/* Category Feed */}
{/* <Animated.FlatList
data={categories}
keyExtractor={item => item.category_id}
renderItem={renderItem}
bounces={false}
scrollEnabled={false}
horizontal
showsHorizontalScrollIndicator={false}
/> */}
{
isLoading ? <View style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}>
<ActivityIndicator size="large" color={R.colors.primary_yellow} />
</View> : <Carousel
renderItem={renderStoryBoard}
data={categories}
initialNumToRender={categories.length}
// contentContainerCustomStyle={{
// left: 0, // Left spacing for the very first card
// paddingRight: 0 //right spacing for very last card
// }}
sliderWidth={R.dimens.screenWidth}
autoplay={true}
itemWidth={R.dimens.screenWidth}
onBeforeSnapToItem={(index) => {
console.log(index);
setIsLoading(true);
console.log(categories[index]);
setCurrentCategory(categories[index].category_id)
onScrollEnd(categories[index].category_id);
}}
enableMomentum={false}
// onSnapToItem={index => {
// console.log(index);
// setIsLoading(true);
// console.log(categories[index]);
// setCurrentCategory(categories[index].category_id)
// onScrollEnd(categories[index].category_id);
// }}
>
</Carousel>
}
{/* Floating Bottom Navigation Bar */}
<BottomTabBar
onTabChnaged={(index) => {
setScreenToShow(index)
}}
/>
</Container>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
// backgroundColor: 'white',
},
header_logo: {
alignSelf: 'center',
height: R.dimens.screenWidth * 0.125,
resizeMode: 'contain',
marginTop: R.dimens.screenWidth * 0.025,
},
prefrences: {
marginTop: R.dimens.screenWidth * 0.05,
height: R.dimens.screenWidth * 0.08,
resizeMode: 'contain',
},
tabItem: {
padding: 10,
marginBottom: 10
},
tabItemSelected: {
backgroundColor: R.colors.primary_yellow,
padding: 10,
marginBottom: 10,
borderRadius: 6
},
scene: {
flex: 1,
},
tabBar: {
marginLeft: 15,
marginRight: 15
}
});
const Container = styled.View`
background: ${(props) => props.theme.background};
`;
const Prefrences = styled.Image`
tint-color: ${(props) => props.theme.text};
`;
const HeaderImage = styled.Image`
tint-color: ${(props) => props.theme.text};
`;
const TabMenuText = styled.Text`
color: ${(props) => props.theme.tab_item_text_color};
`;
export default Dashboard;
Thank you so much.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue in the Dashboard component using the shown Carousel data and onBeforeSnapToItem handler, then compare its behavior with the commented onSnapToItem handler. Trace the callback index against categories while dragging and autoplaying; done means the callback reports the destination category index consistently and the existing category/API update flow uses it correctly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react-native
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100