Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to trigger RefreshControl to open via refreshing prop #10373

Closed
generalChaos opened this issue Oct 13, 2016 · 1 comment
Closed

Unable to trigger RefreshControl to open via refreshing prop #10373

generalChaos opened this issue Oct 13, 2016 · 1 comment
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@generalChaos
Copy link

Issue Description

If you pass TRUE to the RefreshControl 'refreshing' prop, the component will open and show the spinner until it receives a FALSE value. However, this only happens the first time. Any subsequent 'refreshing' state changes won't open the component on TRUE but once it becomes FALSE, the component will open and close at once.

I realize that the RefreshControl may not have been designed to use it this way but the fact that it behaves differently the first time vs. any other time, would indicate a bug.

Steps to Reproduce / Code Snippets

Setup a ListView or ScrollView with a RefreshControl (default refreshing to false). Add a means of changing the 'refreshing' state (button for example). Once clicked, you'll notice the RefreshControl open up until the state is set to FALSE. If you repeat the same process, you will get a different behavior where it open and closes when 'refreshing' is set to FALSE.

Sample code:

'use strict';

import React, {Component} from 'react';
import {
  View,
  StyleSheet,
  Text,
  Image,
  ListView,
  RefreshControl,
  Dimensions,
  TouchableOpacity,
} from 'react-native';

export default class FeedItemListView extends Component {

  constructor(props) {
    super(props);

    this.state = {
      loading: false
    }

    this.toggleLoadingState = this.toggleLoadingState.bind(this);
    this.triggerLoadingState = this.triggerLoadingState.bind(this);
    this.refreshItems = this.refreshItems.bind(this);
  }

  refreshItems(){
    this.setState({loading: true});
    // Do some heavy lifting...
    setTimeout(() => { this.setState({loading: false})}, 3000);
  }

  triggerLoadingState(){
    this.refreshItems();
  }

  renderFeedItem(){
    return (
      <View style={{flex:1, height:200, marginBottom:5, backgroundColor:'#ececec', alignItems:'center', justifyContent:'center'}}>
        <Text>ITEM</Text>
      </View>
    )
  }

  render() {
    let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    let items = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];

    let listView = (
      <View style={{flex:1, marginTop:30}}>
        <TouchableOpacity onPress={this.triggerLoadingState}>
          <Text>Toggle loading state: { this.state.loading } </Text>
        </TouchableOpacity>
        <ListView
          ref="feedItemsList"
          style={styles.itemList}
          dataSource={ds.cloneWithRows(items)}
          renderRow={this.renderFeedItem}
          refreshControl={<RefreshControl ref="rc" style={{backgroundColor:'transparent'}}  refreshing={this.state.loading} onRefresh={this.refreshItems}/>}
          enableEmptySections={true}
          indicatorStyle={"black"} />
      </View>
    );

    return listView;

  };
};

const styles = StyleSheet.create({
  container : {
    flex:1
  },

});

Expected Results

I would expect the RefreshControl to behave the same way every time I change the 'refreshing' state (same behavior as first state change).

Additional Information

There is a way to work around this for the time being. If you over-scroll your ListView (to about y=-60 in iOS) you will trigger the RefreshControl as if it were triggered by a user interaction. Its just not the cleanest way.

  • React Native version: 0.31
  • Platform(s) (iOS, Android, or both?): iOS
  • Operating System (macOS, Linux, or Windows?): macOS
@lacker
Copy link
Contributor

lacker commented Feb 10, 2017

I think something else is the problem here. RefreshControl does work with setting the refreshing state from false -> true -> false -> true a number of times - you can see this in action in UIExplorer, like the example on https://facebook.github.io/react-native/docs/refreshcontrol.html . One possible problem is that there is a race condition in your code here - the setTimeout could be returning after several cycles of toggling the refresh behavior. If you are still running into an issue here then I would suggest asking on Stack Overflow or trying to restart this component from something functional like the example. I am going to close this issue but if I am missing something about how to repro this bug then please feel free to reopen.

@lacker lacker closed this as completed Feb 10, 2017
@facebook facebook locked as resolved and limited conversation to collaborators Jul 19, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

3 participants