I'm developing a chat app in which I have a ChatScreen, and suppose the user scrolls up through the chat, now a scrollToBottom button should appear only if the user is not at bottom (just like popular chat apps), So I tried the following:
First I tried to detect when the user scrolls in a ScrollView, then using the onScroll prop nativeEvent I detected whether or not the user is not at bottom i.e. he/she scrolled up. Then if it is the case, I show the button which should appear in the bottom right corner of the ChatScreen.
Below is the code for my approach. (Is it possible to return a View component inside onScroll prop if the condition satisfies?)
<ScrollView
ref={scrollViewRef}
onScroll={({nativeEvent}) => {
const isCloseToBottom = nativeEvent.layoutMeasurement.height + nativeEvent.contentOffset.y > nativeEvent.contentSize.height - 30;
if (!isCloseToBottom) {
console.log('show scroll to bottom button')
return (
<TouchableOpacity style={{position:'absolute', bottom:40, right:10, backgroundColor:'grey'}} onPress={() => scrollViewRef.current.scrollToEnd()}>
<Icon ... />
</TouchableOpacity>
)
}
}}
>
...
</ScrollView>
So this is what I tried, although when I debug using console.log('show scroll to bottom button') as you can see in the code, it gets triggered, but I'm not able to render/see the Button component on the screen. (I tried setting opacity:1 & zIndex:1 in the style prop of <TouchableOpacity /> but still can't see).
What am I doing wrong? Any solution to this problem would be really appreciated.
Okay, the temporary solution is just create a state and do conditional rendering.
(I think this approach would be not optimum because we would be setting state everytime the user scrolls up or whenever onScroll triggers).
const [isScrolling, setIsScrolling] = useState(false);
<ScrollView
ref={scrollViewRef}
onScroll={({nativeEvent}) => {
const isCloseToBottom = nativeEvent.layoutMeasurement.height + nativeEvent.contentOffset.y > nativeEvent.contentSize.height - 30;
if (!isCloseToBottom) {
setIsScrolling(true);
} else setIsScrolling(false);
}}
>
...
</ScrollView>
{
isScrolling && // return your component here...
}