Skip to content
Advertisement

scrollToIndex out of range: request index1 but maximum is -1 .. React Native

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.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement