在 react-native 中创建一个滑块

Creating a slider in react-native

我正在通过关注 YouTube 视频创建一个反应本机滑块,但这是在基于 class 的组件中,我使用的是基于功能的组件。一切正常,但卡在一个地方。 有人帮我把这段代码转换成功能组件: Class 基于组件

   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
                })
            })

我想将上面的代码转换为函数,但无法正常工作有人告诉我我做错了什么

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

我的完整代码

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;

您可以轻松地将基于 class 的组件转换为功能结构,并与之相对。

只需要注意和一些基本规则:

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)