javascript - React Native 应用程序在获取 API 时冻结
问题描述
嗨,我有一个非常常见的问题,在获取 API 时反应本机应用程序冻结,就像当你获取时你不能点击或做任何事情,直到你的获取结束。
这是我调用获取 APi 的函数的代码
import React, { useEffect, useState } from "react";
import { StyleSheet, View, FlatList } from "react-native";
// Api`s
import { topCategory } from "../../api/appModels/category";
import { banners } from "../../api/appModels/slider";
import { dinamicBlocks } from "../../api/appModels/product";
// Hooks
import useApi from "../../Hooks/useApi";
// UI-Components
import Container from "../../uicomponents/General/Container";
import BannerSlider from "../../uicomponents/Slider/BannerSlider";
import Screen from "../../uicomponents/General/Screen";
import TopProductPattern from "../../uicomponents/Category/pattern/TopProductPattern";
import SliderPlaceholder from "../../uicomponents/Skeleton/Sliders/SliderPlaceholder";
import CategoryAvatarPlaceholder from "../../uicomponents/Skeleton/Category/CategoryAvatarPlaceholder";
import CategoryBlocks from "../../uicomponents/Product/blocks/CategoryBlocks";
import Header from "../../uicomponents/header/Header";
import ActivityIndicator from "../../uicomponents/Loaders/ActivityIndicator";
const HomeScreen = () => {
const {
data: topCategoryList,
loading: topCategoryLoading,
request: categoryRequest,
} = useApi(topCategory);
const {
data: bannersList,
loading: bannerLoading,
request: bannersRequest,
} = useApi(banners);
const {
loading: blocksLoading,
request: blocksRequest,
} = useApi(dinamicBlocks);
const [blocks, setBlocks] = useState([]);
const [indexing, setIndexing] = useState(1);
const [countBlocks, setCountBlocks] = useState(0);
const [loader, setLoader] = useState(false);
useEffect(() => {
// Calling Api`s
categoryRequest();
bannersRequest();
blocksRequest((item) => {
setIndexing(indexing + 1);
setBlocks(item["blocks"]);
setCountBlocks(item["count"]);
}, 1);
}, []);
const loadMore = () => {
if (!blocksLoading) {
blocksRequest((item) => {
setIndexing(indexing + 1);
setBlocks(blocks.concat(item["blocks"]));
console.log(item);
}, indexing);
setLoader(indexing != countBlocks);
}
};
return (
<Screen>
<FlatList
data={blocks}
keyExtractor={(item) => item.categories.toString()}
ListHeaderComponent={
<>
<Header />
{bannerLoading ? (
<SliderPlaceholder />
) : (
<BannerSlider data={bannersList} dots />
)}
<Container>
<View style={{ paddingTop: 10 }}>
{topCategoryLoading ? (
<CategoryAvatarPlaceholder />
) : (
<TopProductPattern data={topCategoryList} />
)}
</View>
</Container>
</>
}
ListFooterComponent={<ActivityIndicator visible={loader} />}
renderItem={({ item }) => (
<CategoryBlocks title={item.blocks_name} data={item.categoriesList} />
)}
onEndReached={loadMore}
onEndReachedThreshold={0.1}
/>
</Screen>
);
};
export default HomeScreen;
const styles = StyleSheet.create({});
这是我获取 API 的代码
import { useState } from "react";
const useApi = (apiFunc) => {
const [data, setData] = useState([]);
const [error, setError] = useState("");
const [loading, setLoading] = useState(true);
const request = async (callBack = () => {}, ...args) => {
setLoading(true);
const response = await apiFunc(...args);
if (!response.ok) return setError(response.problem);
setLoading(false);
setError("");
setData(response.data);
if (response.ok) {
callBack(response.data);
}
};
return {
data,
error,
loading,
request,
setLoading,
setData,
};
};
export default useApi;
我认为 RN-bridge 有问题 请帮助我!
解决方案
可能发生这种情况是因为您设置了 onEndReachedThreshold={0.1}并且当加载数据时,将再发送一次请求并且它会出现问题。
因此,您可以将此值增加到例如0.7。
在react Native官方网站上对EndReachedThreshold是这样解释的:
"列表的底部边缘必须距离内容的末尾多远(以列表的可见长度为单位)才能触发 onEndReached 回调。因此,值为 0.5 将在内容结束时触发 onEndReached在列表可见长度的一半以内。”
推荐阅读
- c# - 从 C# 中的 WebSocket 流中读取整个字符串
- c++ - 在这种情况下如何使用线程?
- rstudio - 如何在 R 的进一步分析中避免行名?
- xpath - 使用python为HTML树中的已知元素自动生成XPath
- shell - 如何使用`sys.args`在命令linux中为文件python执行转义`()`?
- c# - C#如何在另一个类obj中初始化一个类obj的数组?
- android - 在使用 net::ERR_FILE_NOT_FOUND 成功上传后,使用 Ionic4 和 Angular HttpClient 上传分块文件失败
- c - 在函数内部如何检查边缘是否存在,以便在 C 中不会重新插入边缘
- javascript - Moongoose 更新子文档数组对象
- c# - 使用 C# 驱动程序 (MongoDB) 插入一个完整的文档(如果“Id”存在则全部替换 // 如果“Id”不存在则插入)