React Native RefreshControl跳转页面返回后Spinner冻结/消失问题
根因
这是React Native 0.64.x版本的已知原生层bug:当承载RefreshControl的页面失焦被移出视图栈时,原生端的Spinner动画实例会被直接销毁,但JS层维护的refreshing状态仍为true。页面重新聚焦返回时,JS层不会主动触发原生端重建动画实例,因此出现iOS端动画冻结、Android端动画消失的异常。
解决方案
方案1:页面失焦时终止刷新(适配绝大多数业务场景)
监听导航的失焦事件,页面切走时直接重置refreshing状态为false,同时终止正在执行的刷新请求即可。
代码示例:
import { useNavigation } from '@react-navigation/native'; import { useEffect, useState } from 'react'; import { FlatList, RefreshControl } from 'react-native'; const ListPage = () => { const navigation = useNavigation(); const [refreshing, setRefreshing] = useState(false); const onRefresh = async () => { setRefreshing(true); // 执行你的列表刷新请求逻辑 await getListData(); setRefreshing(false); }; useEffect(() => { const unSubscribeBlur = navigation.addListener('blur', () => { if (refreshing) { setRefreshing(false); // 可补充取消未完成刷新请求的逻辑,如cancel axios token } }); return unSubscribeBlur; }, [navigation, refreshing]); return ( <FlatList data={list} renderItem={renderItem} refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />} /> ) }
方案2:需保留刷新状态的场景
如果业务要求切走页面时不终止刷新,返回时仍需展示加载状态,可监听页面聚焦事件,切回时临时切换refreshing状态触发原生动画重建:
useEffect(() => { const unSubscribeFocus = navigation.addListener('focus', () => { if (refreshing) { setRefreshing(false); setTimeout(() => setRefreshing(true), 0); } }); return unSubscribeFocus; }, [navigation, refreshing]);
方案3:底层永久修复
升级React Native版本至0.66.0及以上,该bug已在后续版本的原生代码中修复,无需额外增加业务适配逻辑。
内容的提问来源于stack exchange,提问作者Reo93
相关产品推荐
相关产品推荐

