Ionic-React中hideLoading()函数失效问题求助
Ionic React + Supabase 加载状态异常与useEffect重复触发问题
问题点
- 调用
fetchCategories时,hideLoading()失效,加载动画持续转动 - 页面加载阶段
useEffect钩子触发两次,仅第二次加载状态表现正常 - 核心需求:实现菜单点击逻辑,通过更新
father变量获取对应子分类数据
原代码
const fetchMenu = async () => { try { const { data: menuData, error } = await supabase.from('categoria').select('*').eq('pai', 0); if (error) throw error; setMenu(menuData); console.log(menuData); } catch (error: any) { await showToast({ message: error.message || error.error_description, duration: 5000 }); } } const fetchCategories = async (father: number) => { showLoading(); try { const { data: categoriesData, error } = await supabase.from('categoria').select('*').eq('pai', father); if (error) throw error; setCategories(categoriesData); console.log(categoriesData); } catch (error: any) { await showToast({ message: error.message || error.error_description, duration: 5000 }); } hideLoading(); } useEffect(() => { fetchMenu(); }, []); useEffect(() => { if (father != null){ fetchCategories(father); } }, [father]); return ( <IonPage> {/*CABEÇALHO*/} <IonHeader> <IonToolbar> <IonTitle>Fossil Fashion</IonTitle> </IonToolbar> <IonSegment> {menu?.map((menuPage: any) => ( <IonSegmentButton key={menuPage.id} value={Number(menuPage.id)} onClick={(e) => setFather(Number(e.currentTarget.value))}> <IonLabel>{menuPage.nome}</IonLabel> </IonSegmentButton> ))} </IonSegment> </IonHeader> {/*CORPO*/} <IonContent> <IonSearchbar placeholder="Pesquisa"></IonSearchbar> <IonGrid> {categories?.map((category: any) => ( <IonRow key={category.id}> <IonItemGroup> <IonItemDivider> <IonLabel>{category.nome}</IonLabel> </IonItemDivider> </IonItemGroup> </IonRow> ))} </IonGrid> </IonPage> );
解决方案
1. 修复加载状态失效问题
问题根源在于hideLoading()未被可靠执行,且Ionic的Loading控制器需要通过实例调用dismiss()确保正确关闭。修改fetchCategories:
const fetchCategories = async (father: number) => { // 获取Loading实例,确保每次请求对应唯一实例 const loadingInstance = await showLoading(); try { const { data: categoriesData, error } = await supabase.from('categoria').select('*').eq('pai', father); if (error) throw error; setCategories(categoriesData); } catch (error: any) { await showToast({ message: error.message || error.error_description, duration: 5000 }); } finally { // 无论请求成功/失败,都关闭加载动画 await loadingInstance.dismiss(); } }
若你的showLoading()是全局封装方法,需确保它返回Ionic Loading实例,而非仅触发显示。
2. 处理useEffect重复触发
React 18+开发模式下,StrictMode会强制useEffect执行两次,这是开发环境的校验机制,生产环境会自动消失。若需避免重复请求,可添加状态锁:
const [hasFetchedMenu, setHasFetchedMenu] = useState(false); useEffect(() => { if (!hasFetchedMenu) { fetchMenu(); setHasFetchedMenu(true); } }, [hasFetchedMenu]);
3. 优化菜单点击逻辑
简化onClick事件,直接使用菜单ID,避免类型转换与DOM取值:
<IonSegmentButton key={menuPage.id} value={menuPage.id} onClick={() => setFather(menuPage.id)} > <IonLabel>{menuPage.nome}</IonLabel> </IonSegmentButton>
4. 可选:为菜单加载添加状态控制
若菜单加载也需要显示动画,对fetchMenu做同样改造:
const fetchMenu = async () => { const loadingInstance = await showLoading(); try { const { data: menuData, error } = await supabase.from('categoria').select('*').eq('pai', 0); if (error) throw error; setMenu(menuData); } catch (error: any) { await showToast({ message: error.message || error.error_description, duration: 5000 }); } finally { await loadingInstance.dismiss(); } }
内容的提问来源于stack exchange,提问作者David Valente
相关产品推荐
相关产品推荐

