我有一个react原生应用程序。我有两个api调用:一个用于主页,另一个用于从主页导航到另一个组件。但问题是,如果应用程序首次加载,两个api调用都会被调用。但不必如此--当应用程序首次加载时,只需调用负责构建主页的api调用。
所以我有一个服务:
export const fetchCategoryData = async () => {
try {
const response = await fetch("http://192.168.1.68:8000/api/categories/main_groups/", {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
});
if (!response.ok) {
throw new Error("Network response was not ok");
}
return await response.json();
} catch (error) {
console.error("There was a problem with the fetch operation:", error);
throw error;
}
};
export const fetchSubCategoryData = async () => {
try {
const response = await fetch("http://192.168.1.68:8000/api/categories/2/", {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
});
if (!response.ok) {
throw new Error("Network response was not ok");
}
return await response.json();
} catch (error) {
console.error("There was a problem with the fetch operation:", error);
throw error;
}
};
以及上下文:
export const CategoryContext = createContext();
export const CategoryContextProvider = ({ children }) => {
const [categoryList, setCategoryList] = useState([]);
const [subCategoryList, setSubCategoryList] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [] = useState([]);
const retrieveCategories = () => {
setLoading(true);
setTimeout(() => {
fetchCategoryData()
.then((results) => {
setLoading(false);
setCategoryList(results);
})
.catch((err) => {
setLoading(false);
setError(err);
});
});
};
const retrieveSubCategories = () => {
setLoading(true);
setTimeout(() => {
fetchSubCategoryData()
//.then(subCategoryTransform)
.then((results) => {
setLoading(false);
setSubCategoryList(results.subcategories);
})
.catch((err) => {
setLoading(false);
setError(err);
});
});
};
useEffect(() => {
retrieveCategories();
}, []);
useEffect(() => {
retrieveSubCategories();
}, []);
return (
<CategoryContext.Provider
value={{
lue={{
categoryList,
subCategoryList,
loading,
error,
}}>
{children}
</CategoryContext.Provider>
);
};
因此,当应用程序第一次加载时,只需加载此函数:但是当我查看后端时。我还看到这个函数被调用:检索子类别。
并且这是用户可以导航到API调用的组件的组件:必须触发fetchSubCategoryData:
export const CategoryScreen = ({ navigation }) => {
const { loading, error, categoryList } = useContext(CategoryContext);
return (
<SafeArea>
{loading && (
<LoadingContainer>
<ActivityIndicator animating={true} color={MD2Colors.green200} />
</LoadingContainer>
)}
<Search />
<CategoryList
data={categoryList}
renderItem={({ item }) => {
return (
<TouchableOpacity onPress={() => navigation.navigate("groepen", { category: item.id })}>
<Spacer position="bottom" size="large">
<CategoryInfoCard category={item} />
</Spacer>
</TouchableOpacity>
);
}}
keyExtractor={(item) => item.id}
/>
</SafeArea>
);
};
这是App.js文件:
export default function App() {
const [oswaldLoaded] = useOswald({
Oswald_400Regular,
});
const [latoLoaded] = useLato({
Lato_400Regular,
Lato_900Black,
});
if (!oswaldLoaded || !latoLoaded) {
return null;
}
return (
<>
<ThemeProvider theme={theme}>
<CategoryContextProvider>
<Navigation />
</CategoryContextProvider>
</ThemeProvider>
<ExpoStatusBar style="auto" />
</>
);
}
问题:如何只加载api调用:在应用首次加载时获取CategoryData。
好吧,如果我这样做:
/* eslint-disable prettier/prettier */
import React, { useEffect, useState } from "react";
import { Text, View } from "react-native";
import { CategoryList } from "./category.screen";
import { SafeArea } from "../../../components/utility/safe-area.component";
import { Spacer } from "../../../components/spacer/spacer.component";
import { SubCategoryInfoCard } from "../components/subcategory-info-card.component";
import { TouchableOpacity } from "react-native-gesture-handler";
import { fetchSubCategoryData } from "../../../services/category/category.service";
export const SubCategoryScreen = ({ route }) => {
const [subCatgoryList, setSubCategoryList] = useState([]);
useEffect(() => {
fetchSubCategoryData(route.category).then((data) => {
setSubCategoryList(data);
});
}, [route.category]);
return (
<SafeArea>
<CategoryList
data={subCatgoryList}
renderItem={({ item }) => {
return (
<TouchableOpacity onPress={() => console.log(item)}>
<Spacer position="bottom" size="large">
<SubCategoryInfoCard category={item} />
</Spacer>
</TouchableOpacity>
);
}}
keyExtractor={(item) => item.id}
/>
</SafeArea>
);
};
我得到这个错误:
不变违背:TaskQueue:任务出错:尝试获取超出范围索引NaN的帧
2条答案
按热度按时间zujrkrfu1#
如果我正确理解了您的需求,您所要做的就是从上下文中删除以下行:
然后在从主屏幕导航或返回焦点效果时调用retrieveSubCategories:
这将在主屏幕模糊时调用该函数。从上下文中删除该函数将防止在上下文装载时调用该函数。
qjp7pelc2#
一个可能的解决方案是当你导航到子类别/细节页面时只调用子类别的API,当
useEffect
改变时使用useEffect
来获取类别,我使用了本地状态,但是你显然可以使用上下文中的setState来实现。将
id
传递给fetchSubCategoryData
以使其更具动态性