How to remove the more rendered problem in useAnimatedStyle in react-native?

27 Views Asked by At

here is the below code MAIN CODE :

import React, { useEffect, useRef, useState } from 'react';
import { View, Text, SafeAreaView, StyleSheet, Image, FlatList, TouchableOpacity, StatusBar, Alert } from 'react-native';
import { colorsTemp } from '../configuration/Colors';
import { colors } from '../constants/Colors';
import { width } from '../constants/Scales';
import { useNavigation } from '@react-navigation/native';
import { slides } from '../data/onboarddata';
import Icon from 'react-native-vector-icons/FontAwesome';
import Animated, { useAnimatedStyle, withSpring } from 'react-native-reanimated';
import OnboardBtn from '../components/common/OnboardBtn';
import { centerViewStyle } from '../constants/Styles';
import Loader from '../components/Loaders/Loader.js';

const Onboarding = () => {
    const navigation = useNavigation();
    const [isLoading, setIsLoading] = useState(false);
    const [currIndex, setCurrIndex] = useState(0);
    const ref = useRef(null);
    const ref2 = useRef(null);
    const [onboardSlides, setOnboardSlides] = useState(null);

    useEffect(() => {
        setOnboardSlides(slides);
    }, []);

    const handleIndexChange = () => {
        if (currIndex < (onboardSlides.length - 1)) {
            setCurrIndex(currIndex + 1);
            const currentIndex = currIndex + 1;
            const offset = currentIndex * width;
            ref?.current.scrollToOffset({ offset });
            ref2?.current.scrollToOffset({ offset });
        }
    };

    const updateCurrentIndex = (e) => {
        const contentOffsetX = e.nativeEvent.contentOffset.x;
        const currIndex = Math.round(contentOffsetX / width);
        setCurrIndex(currIndex);
        const offset = currIndex * width;
        ref?.current.scrollToOffset({ offset });
        ref2?.current.scrollToOffset({ offset });
    };

    const renderText = ({ item }) => (
        <View style={style.textContainer}>
            <View style={{ width: width * 0.75, textAlign: 'center' }}>
                <Text style={style.title}>{item.title}</Text>
                <Text style={style.description}>{item.subtitle}</Text>
            </View>
        </View>
    );

    const renderItem = ({ item }) => (
        <View style={style.onboardImageContainer}>
            <Image source={item.image} style={style.onboardImage} resizeMode='stretch' />
        </View>
    );

    const renderIndicators = () => {
        if (!slides || slides.length === 0) return null;

        const indicators = slides.map((slide, index) => {
            const indicatorStyle = animatedStyle(currIndex === index);
            return <Animated.View key={index} style={[style.indicator, indicatorStyle]} />;
        });

        return (
            <View style={style.scrollIndicator}>
                {indicators}
            </View>
        );
    };

    const animatedStyle = (isActive) => useAnimatedStyle(() => {
        const widthVal = withSpring(isActive ? 45 : 12, {
            mass: 1,
            damping: 4,
            stiffness: 100,
            overshootClamping: false,
        });
        const backgroundColor = withSpring(isActive ? colors.primary : colors.tertiary);
        return {
            width: widthVal,
            backgroundColor,
        };
    });

    return (
        <SafeAreaView style={style.safeArea}>
            <StatusBar backgroundColor='black' barStyle='dark-content' />
            {isLoading ? (
                <Loader />
            ) : onboardSlides && onboardSlides.length > 0 ? (
                <>
                    <View style={style.onboardImageWrapper}>
                        <FlatList
                            data={onboardSlides}
                            renderItem={renderItem}
                            keyExtractor={(item) => item.id}
                            horizontal
                            showsHorizontalScrollIndicator={false}
                            pagingEnabled
                            onMomentumScrollEnd={updateCurrentIndex}
                            ref={ref}
                        />
                    </View>
                    <View style={style.textParentContainer}>
                        <FlatList
                            data={onboardSlides}
                            renderItem={renderText}
                            keyExtractor={(item) => item.id}
                            horizontal
                            showsHorizontalScrollIndicator={false}
                            pagingEnabled
                            onMomentumScrollEnd={updateCurrentIndex}
                            ref={ref2}
                        />
                        {renderIndicators()}
                    </View>
                    <View style={[style.footer, (currIndex === (onboardSlides.length - 1)) && { justifyContent: 'center' }]}>
                        {currIndex === (onboardSlides.length - 1) ? (
                            <View style={style.onboardBtnWrapper}>
                                <OnboardBtn
                                    handlePress={() => null}
                                    label="Already Registered? Log in"
                                    buttonStyle={style.btnStyle}
                                    btnTextStyle={style.alreadyRegisteredBtn}
                                />
                                <OnboardBtn
                                    handlePress={() => null}
                                    label="Let's Get Started"
                                    buttonStyle={style.btnStyle}
                                    btnTextStyle={style.getStartBtn}
                                />
                            </View>
                        ) : (
                            <TouchableOpacity onPress={() => handleIndexChange()} style={style.skipBtn}>
                                <Icon name="long-arrow-right" size={30} color={colors.onSecondary} />
                            </TouchableOpacity>
                        )}
                    </View>
                </>
            ) : null}
        </SafeAreaView>
    );
};

const commonBtn = {
    textAlign: 'center',
    textAlignVertical: 'center',
    flex: 1,
    borderRadius: 10,
    fontWeight: 'bold',
    fontSize: 18,
    fontFamily: 'Anta-Regular',
};

const style = StyleSheet.create({
    safeArea: {
        flex: 1,
        backgroundColor: colorsTemp.background,
    },
    onboardImageWrapper: {
        flex: 0.6,
        ...centerViewStyle,
    },
    onboardImageContainer: {
        flex: 1,
        ...centerViewStyle,
    },
    carousalImage: {
        width: width,
        height: '100%',
    },
    textParentContainer: {
        flex: 0.25,
        ...centerViewStyle,
        width: width,
    },
    textContainer: {
        width: width,
        flex: 1,
        ...centerViewStyle,
    },
    title: {
        fontFamily: 'RobotoSlab-VariableFont_wght',
        fontSize: 30,
        color: colors.secondary,
        fontWeight: 'bold',
        textAlign: 'center',
    },
    description: {
        fontSize: 20,
        marginTop: 20,
        ...centerViewStyle,
        textAlign: 'center',
        color: colors.tertiary,
        fontFamily: 'Anta-Regular',
    },
    scrollIndicator: {
        width: width * 0.15,
        marginTop: 10,
        marginBottom: 10,
        flexDirection: 'row',
        alignItems: 'center',
    },
    indicator: {
        // width: 27,
        borderRadius: 5,
        height: 8,
        color: colors.onSecondary,
        marginEnd: 4,
    },
    activeIndicator: {
        // width: 45,
        backgroundColor: colors.primary,
    },
    footer: {
        flex: 0.15,
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'flex-end',
        paddingHorizontal: 8,
    },
    skipBtn: {
        fontWeight: 'bold',
        fontSize: 16,
        marginEnd: 10,
        color: colors.secondary,
    },
    btnStyle: {
        flex: 0.39,
        width: '100%',
    },
    getStartBtn: {
        backgroundColor: colors.primary,
        color: colors.onSecondary,
        ...commonBtn,
    },
    alreadyRegisteredBtn: {
        backgroundColor: colors.tertiary,
        color: colors.onSecondary,
        ...commonBtn,
    },
    onboardBtnWrapper: {
        flex: 1,
        ...centerViewStyle,
        paddingHorizontal: 8,
        gap: 10,
    },
    onboardImage: {
        flex: 0.9,
        width: width,
        borderRadius: 20,
    },
    skipBtn: {
        backgroundColor: colors.tertiary,
        borderRadius: 100,
        padding: 10,
    },
});

export default Onboarding;

if you need the dummy slides data here it is

const slides = [
    {
        id: 1,
        title: "Find Best Salon's Nearby",
        image: require("../assets/images/barbershop_rmbg.gif"),
        subtitle: 'Choose Your Type Salon from different options available Find Your Gromming Partner Today'
    },
    {
        id: 2,
        title: "Attractive Promotions & Offers",
        image: require("../assets/images/promotion_rmbg.gif"),
        subtitle: 'Get Attrative Offers and Discounts (%) on Your Favourite Salon'
    },
    {
        id: 3,
        title: "Professional Salon Specialists",
        image: require("../assets/images/specialist_rmbg.gif"),
        subtitle: 'Choose Your Best Stylist from Our Top Professional Specialists'
    }
]

export {slides}

Note everything is setup properly i have tested and used it but i dont know why the animation is not displaying properly the indicators are working properly but the animation is not shown on them. please help me

dont dislike as i already loosed my account made a new account i dont know why they are doing to me only even my questions were genuine

If you look in the code the animation is working correctly when i have not use the onboardSlides useState and useEffect like this

<View style={style.textParentContainer}>
                        
<FlatList                           
data={onboardSlides}                            
renderItem={renderText}                         
keyExtractor={(item) => item.id}                            
horizontal                          
showsHorizontalScrollIndicator={false}                          
pagingEnabled                           
onMomentumScrollEnd={updateCurrentIndex}                            
ref={ref2}                      
/>
<View style={style.scrollIndicator}>
{onboardSlides.map((item, index) => (
            <Animated.View key={index} style={[style.indicator, animatedStyle(currIndex === index)]} />
        ))
    }
</View>

enter image description here

but why it is not working properly with useEffect and useState **here might be the useAnimatedStyle is in condition that is whyy it is giving error as rendered more than previous render ** i dont know how to solve the problem not

0

There are 0 best solutions below