我有一个平面列表,它渲染了这么多的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>
);
};
我想做的是逐步加载数据,所以从服务器取来的每一个数据都渲染到屏幕上,然后渲染下一个再下一个,怎么做呢?
2条答案
按热度按时间7gs2gvoe1#
对于大数据,你应该使用FlashList而不是FlatList,同时使用分页来获取数据。
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等)对吗?编程愉快。