react-native
react-native copied to clipboard
RefreshControl refresh indicator is not shown on iOS
Description
The refresh indicator for <RefreshControl />
is not shown in<ScrollView>
and related components like <VirtualizedList />
and <FlatList />
etc.. when refreshing is initially set as true
(i.e. refreshing={true}
).
This happens in both, when using Expo Go and when using the build iOS app.
Version
0.69.7, 0.70.6
Output of npx react-native info
System: OS: Linux 5.15 Gentoo Linux CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz Memory: 16.15 GB / 62.44 GB Shell: 5.9 - /bin/zsh Binaries: Node: 16.17.0 - ~/.config/nvm/versions/node/v16.17.0/bin/node Yarn: 1.22.19 - ~/workspace/fgs/mobile/node_modules/.bin/yarn npm: 2.15.12 - ~/workspace/fgs/mobile/node_modules/.bin/npm Watchman: Not Found SDKs: Android SDK: Not Found IDEs: Android Studio: Not Found Languages: Java: 11.0.15 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.0.0 => 18.0.0 react-native: 0.69.6 => 0.69.6 npmGlobalPackages: react-native: Not Found
Steps to reproduce
<ScrollView
contentContainerStyle={styles.scrollView}
refreshControl={
<RefreshControl
refreshing={true}
onRefresh={onRefresh}
/>
}
>
<Text>
This refresh indicator is not shown on iOS
</Text>
</ScrollView>
Snack, code example, screenshot, or link to a repository
https://snack.expo.dev/@danielmorlock/refresh-indicator-bug
I'm also having this issue. To resolve I'm setting refreshing boolean after 10 mills
const fetchData = ()=>{
this.setRefreshing(true)
//... data fetching logic
}
React.useEffect(() => {
setTimeout(() => {
state.fetchData()
}, 10)
}, [])
I am also having this issue, the RefreshControl will not show when initially set to true. It will only show on pull to refresh
I am also having this issue, any update?
I was able to work around with setTimeout as @ngima mentioned above:
import { useEffect, useState } from 'react';
import {
RefreshControlProps,
RefreshControl as RefreshControlRN,
} from 'react-native';
export function RefreshControl({ refreshing, ...other }: RefreshControlProps) {
const [isRefreshing, setRefreshing] = useState(false);
useEffect(() => {
setTimeout(() => {
setRefreshing(refreshing);
}, 10);
}, [refreshing]);
return <RefreshControlRN refreshing={isRefreshing} {...other} />;
}
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.
It’s still a problem…
I am experiencing this exact problem. In the code example (or in your app), if you pull the screen down a bit you can see the loading icon so it's there, just not visible.
same
I have implemented a workaround by programmatically scrolling the view slightly, which makes the hidden refresh control visible on iOS.
import React, { useRef, useState, useEffect } from 'react';
import { ScrollView, RefreshControl } from 'react-native';
const App = () => {
....
const [loading, setLoading] = useState<boolean>(true);
const scrollRef = useRef<ScrollView>(null);
useEffect(() => {
setTimeout(() => {
scrollRef?.current?.scrollTo({ y: -50 });
}, 500);
fetchData();
}, []);
const fetchData = () => {
setLoading(true)
// Your refresh logic here
setLoading(false)
};
....
return (
<ScrollView
ref={scrollRef}
refreshControl={
<RefreshControl
refreshing={loading}
onRefresh={fetchData}
/>
}
>
....
....
</ScrollView>
);
};
The above code uses a useRef
to hold a reference to the <ScrollView>
. In the useEffect
, it programmatically scrolls the view slightly upwards after a delay, which makes the refresh control visible.
This workaround ensures that the refresh control is displayed properly on iOS when the refreshing
prop is true without pulling.
We are having the same issue with FlashList
. It's also reported on that repo but the issue is not of the library but of react native.
https://github.com/Shopify/flash-list/issues/875