I've got a screen with a ScrollView that has a refreshControl property. Turns out that when I refresh my screen, the whole content of the screen moves a few positions down. If I refresh again it keeps going down and so on.

This screenshots are taken right before refreshing and right after. As you see after refreshing some space was added on top of the screen. Why?
Here's what's inside my render function:
render() {
if(this.state.isLoading || this.state.user === null) {
// IF I PUT RETURN NULL HERE IT WORKS FINE,AND THE CONTENT DOESNT GO DOWN
return(<ScrollView contentContainerStyle={{alignItems: "center", flex: 1, justifyContent: 'center'}}>
<Spinner isVisible={true} size={100} type={'Pulse'} color={'#013773'}/>
<DropdownAlert ref={ref => this.dropDownAlertRef = ref} />
</ScrollView>);
}
else {
return (
<ScrollView
refreshControl={
<RefreshControl
refreshing={this.state.isLoading}
onRefresh={this._onRefresh.bind(this)}
/>
}>
<View style={styles.whiteContainer}>
<View style={{backgroundColor: colors.white,paddingVertical: 10, borderStyle: 'solid', borderColor: colors.black}}>
<Text style={{fontStyle: 'italic', fontWeight: 'bold', fontSize:20, marginLeft:20, color: colors.grey}}>
Mis donaciones
</Text>
</View>
{this.state.myDonations.length > 0 ?
<Carousel
ref={(c) => { this._carousel = c; }}
data={this.state.myDonations}
renderItem={this._renderDonation}
sliderWidth={SLIDER_WIDTH}
itemWidth={ITEM_WIDTH2}
inactiveSlideShift={0}
onSnapToItem={(index) => this.setState({ index })}
scrollInterpolator={scrollInterpolator}
slideInterpolatedStyle={animatedStyles}
useScrollView={true}
/>:
<Text style={{fontStyle: 'italic', alignSelf: 'center', fontWeight: 'bold', fontSize:20, marginTop:20, marginBottom: 40, color: colors.grey}}>
¡Nada para mostrar!
</Text>}
</View>
{this.state.user.category === "Voluntario" ?
<View style={styles.whiteContainer2}>
<View style={{backgroundColor: colors.white,paddingVertical:10, borderStyle: 'solid', borderColor: colors.black}}>
<Text style={{fontStyle: 'italic', fontWeight: 'bold', fontSize:20, marginLeft:20, color: colors.grey}}>
Mis entregas
</Text>
</View>
{this.state.myDeliveries.length > 0 ?
<Carousel
ref={(c) => { this._carousel = c; }}
data={this.state.myDeliveries}
renderItem={this._renderDelivery}
sliderWidth={SLIDER_WIDTH}
itemWidth={ITEM_WIDTH2}
inactiveSlideShift={0}
onSnapToItem={(index) => this.setState({ index })}
scrollInterpolator={scrollInterpolator}
slideInterpolatedStyle={animatedStyles}
useScrollView={true}
/> : <Text style={{fontStyle: 'italic', alignSelf: 'center', fontWeight: 'bold', fontSize:20, marginTop:20, marginBottom: 40, color: colors.grey}}>
¡Nada para mostrar!
</Text>}
</View>
: null}
<View style={styles.whiteContainer2}>
<View style={{backgroundColor: colors.white, paddingVertical:10, borderStyle: 'solid', borderColor: colors.black}}>
<Text style={{fontStyle: 'italic', fontWeight: 'bold', fontSize:20, marginLeft:20, color: colors.grey}}>
Pedidos
</Text>
</View>
{this.state.requests.length > 0 ?
<Carousel
ref={(c) => { this._carousel = c; }}
data={this.state.requests}
renderItem={this._renderRequest}
sliderWidth={SLIDER_WIDTH}
itemWidth={ITEM_WIDTH}
inactiveSlideShift={0}
onSnapToItem={(index) => this.setState({ index })}
scrollInterpolator={scrollInterpolator}
slideInterpolatedStyle={animatedStyles}
useScrollView={true}
/> : <Text style={{fontStyle: 'italic', alignSelf: 'center', fontWeight: 'bold', fontSize:20, marginTop:20, marginBottom: 40, color: colors.grey}}>
¡Nada para mostrar!
</Text>}
</View>
<DropdownAlert ref={ref => this.dropDownAlertRef = ref} />
</ScrollView>
);
}
}
_onRefresh looks like this:
_onRefresh = () => {
this.setState({
user: null,
isLoading: true
});
}
isLoading is later set on false when methods inside componentDidUpdate finish loading.
I'm importing RefreshControl and ScrollView from "react-native": "~0.61.4".
Update: As you see inside my render method I got an if-else statement. Turns out if I put return null instead of my spinner inside of the first block, the problem is solved. Why?
Ok, I found the issue. As you see I had a conditional if-else statement in my render method. Turns out I had to add RefreshControl to the ScrollView of the first block of the statement as well.
render() {
if(this.state.isLoading || this.state.user === null) {
return(
<ScrollView contentContainerStyle={{alignItems: "center", flex: 1, justifyContent: 'center'}}
refreshControl={
<RefreshControl
refreshing={false}
onRefresh={this._onRefresh.bind(this)}
/>
}>
...
</ScrollView>);
}
else {
return (
<ScrollView
refreshControl={
<RefreshControl
refreshing={this.state.isLoading}
onRefresh={this._onRefresh.bind(this)}
/>
}>
...
</ScrollView>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With