when I run my application it’s okay and work If I create an array and put it in the data in FlatList like this array
const photos = [ { id: 1, title: "Photo 1" }, { id: 2, title: "Photo 2" }, { id: 3, title: "Photo 3" }, { id: 4, title: "Photo 4" }, { id: 5, title: "Photo 5" }, { id: 6, title: "Photo 6" }, ];
But when I replace the photos array with an API, The app doesn’t work. I tried more than API, I think the error is in my code not in the API, This error appears to me ” scrollToIndex out of range: request index1 but maximum is -1 ” What’s wrong with my code?
import React, { useState, useRef, useEffect } from "react"; import { StyleSheet, View, FlatList, Dimensions, Text, TouchableOpacity, } from "react-native"; import { AntDesign } from "@expo/vector-icons"; import axios from "axios"; const phoneWidth = Dimensions.get("screen").width; const phoneHeight = Dimensions.get("screen").height; function ScrollScreen() { const [index, setIndex] = useState(0); const [border, setBorder] = useState(0); const refContainer = useRef(); const refBox = useRef(); const [data, setData] = useState([]); useEffect(() => { photos(); }, []); function photos() { axios .get("https://jsonplaceholder.typicode.com/photos") .then(async function (response) { setData(response.data); }) .catch((err) => console.error(err)); } useEffect(() => { refContainer.current.scrollToIndex({ animated: true, index }); }, [index]); useEffect(() => { refBox.current.scrollToIndex({ animated: true, index }); }, [index]); const theNext = () => { if (index < photos.length - 1) { setIndex(index + 1); setBorder(index + 1); } }; const thePrevious = () => { if (index > 0) { setIndex(index - 1); setBorder(index - 1); } }; return ( <View style={styles.con}> <AntDesign style={[styles.iconConPosition, { left: phoneWidth * 0.05 }]} onPress={thePrevious} size={55} color="#0dddcb" name="caretleft" /> <AntDesign style={[styles.iconConPosition, { right: phoneWidth * 0.05 }]} onPress={theNext} size={55} color="#0dddcb" name="caretright" /> <FlatList scrollEnabled={false} ref={refContainer} data={data} // data={photos} keyExtractor={(item, index) => item.id.toString()} style={styles.flatList} renderItem={({ item, index }) => ( <View style={{ height: 150, width: phoneWidth * 0.7, margin: 50, backgroundColor: "red", alignSelf: "center", justifyContent: "center", alignItems: "center", }} > <Text>{item.id}</Text> <Text>{item.title}</Text> </View> )} horizontal pagingEnabled //تفعيل خاصية التمرير showsHorizontalScrollIndicator={false} /> <FlatList ref={refBox} data={data} // data={photos} keyExtractor={(item, index) => item.id.toString()} style={styles.flatList} renderItem={({ item, index }) => ( <TouchableOpacity onPress={() => { setIndex(index); setBorder(index); }} style={ border === index ? { height: 100, width: phoneWidth * 0.4, margin: 7, backgroundColor: "gray", alignSelf: "center", justifyContent: "center", alignItems: "center", borderWidth: 2, borderColor: "blue", } : { height: 100, width: phoneWidth * 0.4, margin: 7, backgroundColor: "gray", alignSelf: "center", justifyContent: "center", alignItems: "center", } } > <Text>{item.id}</Text> <Text>{item.title}</Text> </TouchableOpacity> )} horizontal /> <Text>{index}</Text> </View> ); } export default ScrollScreen;
Advertisement
Answer
Initially data
is an empty array, but index
is set to 0
. On the first invocation of the useEffect
that tries to scroll, there is an error because scrollToIndex(0)
is an error when data
is empty, since there is no item for index 0
.
Try initializing the border
and index
state to -1
instead of 0
like:
const [index, setIndex] = useState(-1); const [border, setBorder] = useState(-1);
On a separate but related note the theNext
function has an error, it should be checking data.length
instead of photos.length
.