使用React Native从api动态获取数据时自动图像轮播的问题

时间:2020-06-05 03:13:07

标签: react-native axios react-hooks carousel

我正在实现自动旋转的图像轮播。当我用静态数据实现它(例如:用数组创建一个常量)时,它的工作方式就和我想要的一样。

但是,当我使用axios从api获取数据时,carrosuel的行为错误。错误行为如下:

在轮播上滑动到第二个图像,然后继续前进到第三个图像,先回到第一个图像,然后再回到第三个图像,再回到第四个图像,再回到第一个图像,然后转到第一个图像。第四,此行为重复x次。

所以我认为问题出在我使用axios时。我附上了干预我当前提出的问题的类的代码。

我正在使用带有钩子和axios的react native 0.62

HomeScreen.js

import React, { useEffect, useState } from "react";
import { View } from "react-native";
import CategoriesScreen from "./Categories/CategoriesScreen";
import { ScrollView } from "react-native-gesture-handler";
import Carousel from "./Banner/BannerOficial";
import { axiosClient } from "../../config/axios";

export default function HomeScreen({ navigation }) {


  const [banners, setBanners] = useState([]);

  useEffect(() => {
    getBannersAPI();
  }, []);

  function getBannersAPI(){
    axiosClient
    .get("/service/banner_available")
    .then(async function (response) {
      setBanners(response.data);
    })
    .catch(function (error) {
      console.log("Error cargando los banners: ", error);
    });
  }
  
  return (
    <View style={{ flex: 1 }}>
      <ScrollView>
        <Carousel data={banners} />
        <CategoriesScreen navigation={navigation} />
      </ScrollView>
    </View>
  );
}

Carousel.js

import React, { useState, useEffect } from 'react'
import { View, Text, StyleSheet, Dimensions, FlatList, Animated } from 'react-native'
import CarouselItem from './BannerItem'


const { width, heigth } = Dimensions.get('window')
let flatList

function infiniteScroll(dataList){
    const numberOfData = dataList.length
    let scrollValue = 0, scrolled = 0

    setInterval(function() {
        scrolled ++
        if(scrolled < numberOfData)
        scrollValue = scrollValue + width

        else{
            scrollValue = 0
            scrolled = 0
        }

        this.flatList.scrollToOffset({ animated: true, offset: scrollValue})
        
    }, 3000)
}


const Carousel = ({ data }) => {
    const scrollX = new Animated.Value(0)
    let position = Animated.divide(scrollX, width)
    const [dataList, setDataList] = useState(data)

    useEffect(()=> {
        setDataList(data)
        infiniteScroll(dataList)
    })


    if (data && data.length) {
        return (
            <View>
                <FlatList data={data}
                ref = {(flatList) => {this.flatList = flatList}}
                    keyExtractor={(item, index) => 'key' + index}
                    horizontal
                    pagingEnabled
                    scrollEnabled
                    snapToAlignment="center"
                    scrollEventThrottle={16}
                    decelerationRate={"fast"}
                    showsHorizontalScrollIndicator={false}
                    renderItem={({ item }) => {
                        return <CarouselItem item={item} />
                    }}
                    onScroll={Animated.event(
                        [{ nativeEvent: { contentOffset: { x: scrollX } } }]
                    )}
                />

                <View style={styles.dotView}>
                    {data.map((_, i) => {
                        let opacity = position.interpolate({
                            inputRange: [i - 1, i, i + 1],
                            outputRange: [0.3, 1, 0.3],
                            extrapolate: 'clamp'
                        })
                        return (
                            <Animated.View
                                key={i}
                                style={{ opacity, height: 10, width: 10, backgroundColor: '#595959', margin: 8, borderRadius: 5 }}
                            />
                        )
                    })}

                </View>
            </View>
        )
    }

    console.log('Please provide Images')
    return null
}

const styles = StyleSheet.create({
    dotView: { flexDirection: 'row', justifyContent: 'center'}
})

export default Carousel

CarouselItem.js

import React from "react";
import { View, StyleSheet, Text, Image, Dimensions} from 'react-native';

const { width, height} = Dimensions.get('window')

const CarouselItem = ({item}) => {
    return(
        <View style={styles.cardView}>
            <Image style={styles.image} source = {{ uri: item.imagePath}}/>
        </View>
    )
}

const styles = StyleSheet.create({
    cardView:{
        flex:1,
        width: width -20,
        height: height / 7,
        backgroundColor: "white",
        margin: 10,
        borderRadius: 10,
        shadowColor: "#000",
        shadowOffset: {width: 0.5, height: 0.5},
        shadowOpacity: 0.5, 
        shadowRadius: 3,
        elevation: 5,
    },
    image: {
        width: width-20,
        height: height / 3,
        borderRadius: 10
    }
})

export default CarouselItem

0 个答案:

没有答案