javascript 如何在RN中实现平面表的数据渐进加载?

tmb3ates  于 2023-01-11  发布在  Java
关注(0)|答案(2)|浏览(105)

我有一个平面列表,它渲染了这么多的renderItem与数据加载从我的自定义后端。问题是当连接速度慢或当我重新加载这么多次,数据将不会加载预期和数据不渲染到屏幕或应用程序将崩溃。我使用自定义钩子来获取数据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 };
};

渲染项目代码:

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

屏幕代码:

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

我想做的是逐步加载数据,所以从服务器取来的每一个数据都渲染到屏幕上,然后渲染下一个再下一个,怎么做呢?

7gs2gvoe

7gs2gvoe1#

对于大数据,你应该使用FlashList而不是FlatList,同时使用分页来获取数据。

rsl1atfo

rsl1atfo2#

您所说的“数据无法按预期加载”的确切含义是什么?哪些方面无法满足您的预期?
FlatList只消耗你提供的数据并显示给你,从我看到的情况来看,你的API调用/api/long={}&lat={}返回了所有的数据,这些数据(假设)是在你的数据库中设置的?
因此,为了优化前端性能,你可以将从API中获取的数据存储在某个地方,然后分步骤加载到data中,假设api返回30个结果,并且你已经以正确的方式将它们保存在代码中,下一步是获取6个结果(或者8或10个,随便你怎么想),并将其放入FlatList的data-attribute状态(使用state或redux等),并从事件onEndReached的30个结果中加载更多数据。

**重要提示:**以上解释的步骤只是为了优化前端。我认为您可能需要重写API端点来逐步加载数据,而不是逐步显示数据。您不必从数据中预加载1000行数据(希望是在数据库中)并通过互联网推送它们。这是在后端浪费处理/网络资源=〉您可以在同一时间同时为100个用户提供10行数据,而不是向一个用户发送1000行数据。几乎在同一时间,您不能像这样计算,但我想您理解了我的观点。因此:让你自己的逻辑如何加载这些一步一步。

添加另一个查询参数(如?lng=37.7749295&lat=-122.4194155&offset={})并从数据源(偏移量=0:限值10,偏移=1:极限偏移量 *10、10等)对吗?
编程愉快。

相关问题