Adil Ijaz
Adil Ijaz

Reputation: 135

Creating a slider in react-native

I'm creating a react-native slider by following a YouTube video but that's in class based component and I'm using functional based component. Every thing is working fine but get stuck at one place. Someone help me convert this code into functional component: Class Based Component

   this.setState(prev=> ({ selectedIndex: prev.selectedIndex === this.props.images.length-1 ? 0 : prev.selectedIndex + 1}),
            ()=>{
                this.scrollRef.current.scrollTo({
                    animate: true,
                    y: 0,
                    x: ScreenWidth * this.state.selectedIndex
                })
            })

I want to convert this above code into function but not working properly someone tell me what I'm doing wrong

 setInterval(()=>{
      setImgActive(imgActive+1)
      sliderCustom.current.scrollTo({
        animated:true,
        y:0,
        x:width*imgActive
      })
     },6000)

Full Code of Mine

import React, { useState, useEffect, useRef, useCallback } from "react";
import {
  ActivityIndicator,
  Image,
  StyleSheet,
  Text,
  View,
  Platform,
  FlatList,
  TouchableOpacity,
  ScrollView,
  Dimensions
} from "react-native";
import {
  widthPercentageToDP as wp,
  heightPercentageToDP as hp,
} from "react-native-responsive-screen";
// color
import colors from "../colors/colors";
// api
import { getBannersApi } from "../api/apis";
import {media} from "../api/config.json"
// Carousel
import { FlatListSlider } from "react-native-flatlist-slider";
import Carousel,{ ParallaxImage }  from 'react-native-snap-carousel';

const {width, height} = Dimensions.get('window')
const Preview = ({
    item,
    onPress,
    index,
  }) => {
      
    return(
        <TouchableOpacity
      style={[styles.videoContainer,{
          // marginLeft:index == 0 ? wp('2'): 0,
      }]}
     >
      <View style={[styles.imageContainer, styles.shadow]}>
        <Image
          style={{height:hp('22'), width:wp('90'), borderRadius:10,}}
          source={item.banner}
        />
      </View>
     
    </TouchableOpacity>
    )
}

const SliderCarouselFlat = () => {
  const [banners, setBanners] = useState([])
  const [activeIndex, setActiveIndex] = useState(0)
  const [imgActive, setImgActive] = useState(0)
  const [load, setLoad] = useState(false)

  const slider = useRef()
  const caro = useRef()
  const sliderCustom = useRef()
  // console.log('Banners State', banners)
  const images = [
    {
      banner:require('../images/banner.png'),
    },
    {
        banner:require('../images/bannert.png'),
    },
    {
      banner:require('../images/bannert.png'),
  },
  {
    banner:require('../images/bannert.png'),
},

    
  ];

  useEffect(()=>{
    getBanners()
   if(load == true){
     setInterval(()=>{
    
       setImgActive(imgActive+1)
       sliderCustom.current.scrollTo({
         animated:true,
         y:0,
         x:width*imgActive
       })
      },6000)
   }
  },[])


  // API CALL
  const getBanners =async () =>{
    try{
      const {data} =await getBannersApi()
      
       if(data.status == true){
        
          setBanners(data)
          setLoad(true)
          }
      
    }catch(e){
      console.log(e)
    }
  }
  const _renderItem= ({item,index})=>{
    return (
      <View>
         <Image
          style={{height:hp('22'), width:wp('90'), borderRadius:10,}}
          source={item.banner}
        />
      </View>

    )
}
  



  const setSelIndex = (event) =>{
    const viewSize= event.nativeEvent.layoutMeasurement.width;
    const contentOffset = event.nativeEvent.contentOffset.x;

    const selIndex = Math.floor(contentOffset/viewSize)
    setImgActive(selIndex)

  }
  return (
    <View style={styles.container}>
      <View style={styles.wrap} >
      {
        load == false?
        <ActivityIndicator size="small" color={colors.primary} />
        :
        <View>
           <ScrollView
       ref={sliderCustom}
       onMomentumScrollEnd={setSelIndex}
       showsHorizontalScrollIndicator={false}
       pagingEnabled
       horizontal
       autoScroll
       style={styles.wrap}
      >
        {
        banners.all_banners.map((item,index)=>{
          
          return(
          <View >
              <Image
              source={{uri:item.banner}}
              resizeMode="contain"
              style={{height:hp('22'), width:wp('90'), borderRadius:10, marginHorizontal:index == 0 ? wp(2):wp(4)}}
            />
          </View>
          )
        })
      }
      </ScrollView>
      <View style={styles.wrapDots } >
      {
         banners.all_banners.map((item, index)=>(
           <Text
            key={index}
            style={imgActive==index?styles.dotActive:styles.dot }
           >
            ●
           </Text>
          ))
        }
      </View>
        </View>
      }
      </View>

    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flexGrow: 1,
  },
  videoContainer:{
  //  paddingHorizontal:hp('2'),
      
  },
  wrap:{
  
  },
  wrapDots:{
    position:'absolute',
    bottom:0,
    flexDirection:'row',
    alignSelf:'center'
  },
  dotActive:{
    margin:2,
    color:'#ffffff',
  },
  dot:{
    margin:2,
    color:'#ffffff80'
  }
});

export default SliderCarouselFlat;

Upvotes: 1

Views: 1017

Answers (1)

nima
nima

Reputation: 8915

You can easily convert the class-based component to functional structure and vis vers.

Just need attention and some basic rules:

setInterval(() => {
  setImgActive(prevSTate => ({ 
      selectedIndex: prevState.selectedIndex === props.images.length-1 ? 0 : prevState.selectedIndex + 1
    }))
  slider .current.scrollTo({
    animated:true,
    y:0,
    x:width*imgActive
  })

}, 60000)

Upvotes: 1

Related Questions