使用Api Sauce渲染FlatList数据异常问题求助
问题:Expo重载时FlatList无法渲染API数据,保存代码后正常显示
问题详情
开发一款获取客户数据的简易移动应用,其他功能均正常,但遇到以下问题:
- API调用已成功,能从数据库获取全部数据
- Expo重载时数据无法显示,按下
cmd+s保存代码后数据却能正常展示 - 组件挂载时数据未被渲染,不清楚原因
相关代码
组件代码
// 封装的API调用钩子 import useApi from "../../hooks/useApi"; const getFoldersApi = useApi(foldersApi.getFolders); const [foldersList, setFoldersList] = useState([]); useEffect(() => { getFoldersApi.request(); setFoldersList(getFoldersApi.data); }, []); <FlatList style={styles.folders} data={foldersList} keyExtractor={(folder) => folder.Guid} renderItem={({ item, index }) => ( <Card title={item.Nom} image={folderIcon} index={index} folderType={item.TypeDossier} folderState={item.EtatDossier} depositDate={item.DatedepoDossier} shippingType={item.TypeManifeste} vendor={item.Fournisseur} onPress={() => navigation.navigate("Détails", item)} /> )} />
API钩子代码
import { useState } from "react"; export default useApi = (apiFunc) => { const [data, setData] = useState([]); const [error, setError] = useState(false); const [loading, setLoading] = useState(false); const request = async (...args) => { setLoading(true); const response = await apiFunc(...args); setLoading(false); if (!response.ok) return setError(true); setError(false); setData(response.data); }; return { data, error, loading, request }; };
问题原因
useEffect中调用getFoldersApi.request()是异步操作,执行setFoldersList(getFoldersApi.data)时,API请求还未完成,getFoldersApi.data仍为初始空数组。而按下cmd+s保存代码时,组件重新渲染,此时API请求已完成,getFoldersApi.data已有数据,因此FlatList能正常渲染。
解决方案
方案1(推荐):直接使用useApi返回的data作为数据源
不需要额外维护foldersList状态,直接用useApi返回的响应式data:
import useApi from "../../hooks/useApi"; const getFoldersApi = useApi(foldersApi.getFolders); useEffect(() => { getFoldersApi.request(); }, []); <FlatList style={styles.folders} data={getFoldersApi.data} // 直接使用getFoldersApi.data keyExtractor={(folder) => folder.Guid} renderItem={({ item, index }) => ( <Card title={item.Nom} image={folderIcon} index={index} folderType={item.TypeDossier} folderState={item.EtatDossier} depositDate={item.DatedepoDossier} shippingType={item.TypeManifeste} vendor={item.Fournisseur} onPress={() => navigation.navigate("Détails", item)} /> )} />
方案2:等待异步请求完成后更新状态
如果需要单独维护foldersList,可在useEffect中使用异步函数等待请求完成:
import useApi from "../../hooks/useApi"; const getFoldersApi = useApi(foldersApi.getFolders); const [foldersList, setFoldersList] = useState([]); useEffect(() => { const fetchAndSetData = async () => { await getFoldersApi.request(); setFoldersList(getFoldersApi.data); }; fetchAndSetData(); }, []); // FlatList部分保持不变
内容的提问来源于stack exchange,提问作者Sb Zakaria
相关产品推荐
相关产品推荐

