Home > front end >  React-Native: RefreshControl on ScrollView with nested View won't show animation
React-Native: RefreshControl on ScrollView with nested View won't show animation

Time:05-10

So I am pretty new to React Native and I'm trying to implement a list of contacts which is refreshable. However I cannot get it to work (probably because I missed something). I don't get any errors, I simply cannot pull down to get the animation.

I have created a wrapper component which is used as a basis for all my other stuff besides the contact-list as well.

const Wrapper = ({ refreshing, onRefresh, children }) => {
    const theme = useColorScheme();

    return refreshing === null || onRefresh == null ? (
        <SafeAreaView style={{ flex: 1 }}>
            <ScrollView
                style={theme === "light" ? styles.container_light : styles.container_dark}
                contentContainerStyle={{ flexGrow: 1 }}
            >
                <View style={styles.wrapper}>{children}</View>
            </ScrollView>
        </SafeAreaView>
    ) : (
        <SafeAreaView style={{ flex: 1 }}>
            <ScrollView
                style={theme === "light" ? styles.container_light : styles.container_dark}
                contentContainerStyle={{ flexGrow: 1 }}
            >
                <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
                <View style={styles.wrapper}>{children}</View>
            </ScrollView>
        </SafeAreaView>
    );
};

export default Wrapper;

As seen above, refreshing & onRefresh get passed to the Wrapper, because the ScrollView is located there.

Now in my contact list, I put all my contacts inside that wrapper element and pass refreshing & onRefresh to the Wrapper. I also have a header and a FloatingActionButton on that screen. The screen takes up 100% of the height because I want that FloatingActionButton on the bottom right of my screen.

// outside my contact-list component:
const wait = (timeout) => {
    return new Promise((resolve) => setTimeout(resolve, timeout));
};

// in my contact-list component:
const [refreshing, setRefreshing] = useState(false);

const onRefresh = useCallback(() => {
    setRefreshing(true);
    wait(2000).then(() => setRefreshing(false));
}, []);


<Wrapper refreshing={refreshing} onRefresh={onRefresh}>
    <Text style={theme === "light" ? globalStyles.heading_light : globalStyles.heading_dark}>
        {t("ContactsIndexHeader")}
    </Text>

    <View style={{ marginTop: 30 }}>
        {contacts.length > 0 ? letters.map((letter) => {
            return (...); // Check last name of contact & display if equal to letter
        })
        : null}
    </View>

    <FloatingActionButton icon="plus" onPress={() => navigation.navigate("ContactsCreate")} />
</Wrapper>

CodePudding user response:

I believe that refresh control should be specified as a prop and not as a child of scroll view, example:

<ScrollView
    refreshControl={
        <RefreshControl
            refreshing={refreshing}
            onRefresh={onRefresh} 
        />
    }
 />
  • Related