How to make flatlist to load data gradually in RN?

Viewed 34

i have a flatlist which renders so many renderItem with data loaded from my custom backend . the problem is when connection is slow or when i reload so many times , data will not load as expected and the data not render to the screen or the app will crash . im using a custom hook to fetch data HttpHook :

import { useState, useCallback } from "react";

export const useHttpClient = () => {
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState();

  const sendRequest = useCallback(
    async (
      URL,
      method = "GET",
      body = null,
      headers = {},
      credentials = "include"
    ) => {
      setIsLoading(true);
      try {
        const res = await fetch(URL, { method, body, headers, credentials });
        const resData = res.json();

        if (!res.ok) {
          setError(resData.error);
        }
        setIsLoading(false);
        return resData;
      } catch (error) {
        setIsLoading(false);
        setError(error.message);
      }
    },
    []
  );

  const clearError = () => {
    setError(null);
  };
  return { isLoading, error, clearError, sendRequest };
};

render item code :

const renderItemComponent = ({ item }) => {
  return (
    <Spacer dir="vertical" size="small">
      <RestaurantCard restaurant={item} />
    </Spacer>
  );
};

screen code :

export const RestaurantsScreen = () => {
  const { isLoading, error, clearError, sendRequest } = useHttpClient();
  const restaurantsContext = useContext(RestaurantsContext);

  const fetchRestaurants = async () => {
    const URL =
      "http://localhost:3000/api/location?lng=37.7749295&lat=-122.4194155";
    const { results } = await sendRequest(URL);
    const mappedResult = results.map((restaurant) => {
      return {
        ...restaurant,
        isOpenNow:
          restaurant.opening_hours && restaurant.opening_hours.open_now,
        isClosedTemporarily:
          restaurant.business_status === "CLOSED_TEMPORARILY",
      };
    });
    const loadedRestaurants = camelize(mappedResult);
    restaurantsContext.restaurants = loadedRestaurants;
    console.log(restaurantsContext.restaurants);
  };

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

  return (
    <SafeArea>
      <SearchContainer>
        <Searchbar placeholder="Search ..." />
      </SearchContainer>
      {isLoading && (
        <Center>
          <Text>Loading Restaurants ... </Text>
        </Center>
      )}
      {isLoading && restaurantsContext.restaurants.length === 0 && (
        <Center>
          <Text>No Restaurants Available</Text>
        </Center>
      )}
      {!isLoading && restaurantsContext.restaurants.length > 0 && (
        <RestaurantList
          data={restaurantsContext.restaurants}
          renderItem={renderItemComponent}
          keyExtractor={(item) => item.name}
          initialNumToRender={3}
        />
      )}
    </SafeArea>
  );
};

what i want to do is to load data gradually , so every data that fetched from the server renders to the screen and then render the next one and next one . how can i do this ?

1 Answers

For big data you should use FlashList instead of FlatList. Also use pagination for data fetching.

Related