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,
},
});