1

Having an issue with my ScrollView. I use it in a couple different places in my application, and most of them are working exactly as expected.

However, in one component it is working very strangely - if I swipe quickly, it will sometimes work, but usually not, and if I swipe gently or only a small amount, it doesn't work at all. I render a couple different things inside the ScrollView, but can't work out why any of them might be causing a problem, and can't spot anything obvious that's different between the one that doesn't work and the others, so I'm really at my wits end!

I am testing it on Android.

Here's what I think are the relevant bits of code for the page, but I've also put the full code below - please let me know if there's any other detail that would be useful:

const wait = (timeout) => {
  return new Promise((resolve) => setTimeout(resolve, timeout));
};

export default function PotluckStandalone(props) {
  const potlucks = useSelector((state) => state.potlucks);
  const potluck = potlucks.find(
    ({ idCode }) => idCode === props.route.params.idCode
  );

  const [refreshing, setRefreshing] = React.useState(false);

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

  const dispatch = useDispatch();


  const Reply = () => {
    return (
      <View>
        <FlatList
          keyExtractor={(item, index) => index}
          data={potluck.replies}
          renderItem={({ item }) => (
            <View>
              <Card
                containerStyle={{
                  borderRadius: 12,
                  borderWidth: 1,
                  elevation: 0,
                  backgroundColor: "rgba(255,255,255,0.6)",
                  overflow: "hidden",
                }}
                style={{ borderColor: "rgba(255,255,255,0.1)" }}
              >
                <Card.Title>{item.bringer} is bringing...</Card.Title>
                <Card.Divider />
                {item.bringing.map((bringItem, index) => {
                  return (
                    <Text key={index}>
                      {bringItem}
                      {index < item.bringing.length - 2 ? ", " : ""}
                      {index === item.bringing.length - 2 ? " and " : ""}
                    </Text>
                  );
                })}
              </Card>
            </View>
          )}
        />
      </View>
    );
  };

  if (!potluck) {
    return <Text>Loading...</Text>;
  } else {
    return (
      <ImageBackground
        source={require("../images/background.png")}
        style={{ width: "100%", height: "100%", alignItems: "center" }}
      >
        <ScrollView
          style={styles.page}
          refreshControl={
            <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
          }
        >
          <Card
            containerStyle={{
              borderRadius: 12,
              borderWidth: 1,
              elevation: 0,
              backgroundColor: "rgba(255,255,255,0.6)",
              overflow: "hidden",
            }}
            style={{ borderColor: "rgba(255,255,255,0.1)" }}
          >
            <Card.Title>
              <Text>{potluck.potluckTitle}</Text>
            </Card.Title>
            <Card.Divider />

            <Text>Host: {potluck.potluckHost}</Text>
            <Text>Theme: {potluck.potluckTheme}</Text>
            <Text>
              Essentials:
              {potluck.essentials.map((essential, index) => {
                return (
                  <Text key={index}>
                    {" "}
                    {essential}
                    {index < potluck.essentials.length - 2 ? ", " : ""}
                    {index === potluck.essentials.length - 2 ? " and " : ""}
                  </Text>
                );
              })}
            </Text>
            <Card.Divider />

            <Reply />
          </Card>

          <Bringing
            potluck={potluck}
            setReplySnack={() => setReplySnack(true)}
          />

        </ScrollView>
      </ImageBackground>
    );
  }
}

const styles = StyleSheet.create({
  page: {
    width: "90%",
    paddingTop: 50,
    paddingBottom: 250,
  },
});

Full code here:

import { StatusBar } from "expo-status-bar";
import React, { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import {
  ScrollView,
  View,
  Text,
  FlatList,
  RefreshControl,
  SafeAreaView,
  Button,
  Share,
  ImageBackground,
} from "react-native";
import { useDispatch } from "react-redux";
import { Card } from "react-native-elements";
import Bringing from "./Bringing";
import { updatePotluck } from "../actions/potlucks";
import { render } from "react-dom";
import { StyleSheet } from "react-native";

import Snackbar from "react-native-snackbar-component";

const wait = (timeout) => {
  return new Promise((resolve) => setTimeout(resolve, timeout));
};

export default function PotluckStandalone(props) {
  const potlucks = useSelector((state) => state.potlucks);
  const potluck = potlucks.find(
    ({ idCode }) => idCode === props.route.params.idCode
  );

  const [refreshing, setRefreshing] = React.useState(false);

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

  const dispatch = useDispatch();

  const [potluckSnackIsVisible, setPotluckSnackIsVisible] = useState(false);
  const [replySnackVisible, setReplySnackVisible] = useState(false);

  React.useEffect(() => {
    props.route.params.success
      ? setPotluckSnackIsVisible(true)
      : setPotluckSnackIsVisible(false);
  }, []);

  const onShare = async () => {
    try {
      const result = await Share.share({
        message: `Join me for a potluck | whatLuck https://whatluck.netlify.app/potlucks/${potluck.idCode}`,
      });
      if (result.action === Share.sharedAction) {
        if (result.activityType) {
          // shared with activity type of result.activityType
        } else {
          // shared
        }
      } else if (result.action === Share.dismissedAction) {
        // dismissed
      }
    } catch (error) {
      alert(error.message);
    }
  };

  const setReplySnack = () => setReplySnackVisible(true);

  const Reply = () => {
    return (
      <View>
        <FlatList
          keyExtractor={(item, index) => index}
          data={potluck.replies}
          //style={styles.flatlist}
          renderItem={({ item }) => (
            <View>
              <Card
                containerStyle={{
                  borderRadius: 12,
                  borderWidth: 1,
                  elevation: 0,
                  backgroundColor: "rgba(255,255,255,0.6)",
                  overflow: "hidden",
                }}
                style={{ borderColor: "rgba(255,255,255,0.1)" }}
              >
                <Card.Title>{item.bringer} is bringing...</Card.Title>
                <Card.Divider />
                {item.bringing.map((bringItem, index) => {
                  return (
                    <Text key={index}>
                      {bringItem}
                      {index < item.bringing.length - 2 ? ", " : ""}
                      {index === item.bringing.length - 2 ? " and " : ""}
                    </Text>
                  );
                })}
              </Card>
            </View>
          )}
        />
      </View>
    );
  };

  if (!potluck) {
    return <Text>Loading...</Text>;
  } else {
    return (
      <ImageBackground
        source={require("../images/background.png")}
        style={{ width: "100%", height: "100%", alignItems: "center" }}
      >
        <ScrollView
          style={styles.page}
          refreshControl={
            <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
          }
        >
          <Card
            containerStyle={{
              borderRadius: 12,
              borderWidth: 1,
              elevation: 0,
              backgroundColor: "rgba(255,255,255,0.6)",
              overflow: "hidden",
            }}
            style={{ borderColor: "rgba(255,255,255,0.1)" }}
          >
            <Card.Title>
              <Text>{potluck.potluckTitle}</Text>
            </Card.Title>
            <Card.Divider />

            <Button onPress={onShare} title="Invite your friends" />

            <Text>Host: {potluck.potluckHost}</Text>
            <Text>Theme: {potluck.potluckTheme}</Text>
            <Text>
              Essentials:
              {potluck.essentials.map((essential, index) => {
                return (
                  <Text key={index}>
                    {" "}
                    {essential}
                    {index < potluck.essentials.length - 2 ? ", " : ""}
                    {index === potluck.essentials.length - 2 ? " and " : ""}
                  </Text>
                );
              })}
            </Text>
            <Card.Divider />

            <Reply />
          </Card>

          <Bringing
            potluck={potluck}
            setReplySnack={() => setReplySnack(true)}
          />

          <Snackbar
            visible={potluckSnackIsVisible}
            textMessage="Potluck created successfully!"
            autoHidingTime={3000}
          />
          <Snackbar
            visible={replySnackVisible}
            textMessage="Reply posted successfully!"
            autoHidingTime={3000}
          />
        </ScrollView>
      </ImageBackground>
    );
  }
}

const styles = StyleSheet.create({
  page: {
    width: "90%",
    paddingTop: 50,
    paddingBottom: 250,
  },
});
3
  • 2
    Does this answer your question? FlatList inside ScrollView doesn't scroll Commented Oct 27, 2021 at 10:34
  • Thanks @wowandy! That definitely makes it a lot better - but it is still a lot less responsive than on my other components. If I swipe quickly, it works well, but if I do it more gently then it isn't picking it up. I'm going to have a look to see if I can find a way to configure how responsive it is. Commented Oct 27, 2021 at 10:53
  • Okay, not sure why (!), but if I wrap the ScrollView in a <TouchableOpacity activeOpacity={1}> tag, then it works fine - but I have to import TouchableOpacity from react-native, and ScrollView and FlatList from react-native-gesture-handler, or it doesn't work. 🤔 Thanks for pointing me in the right direction @wowandy! Commented Oct 27, 2021 at 11:10

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.