Arpith Siromoney 💬

Pull to refresh in React Native

I’m building an app to share notes (Constellational — sign up here!) and one thing I’ve wanted is to be able to use it on my iPad as well as my phone. To do this, I need some way to refresh the list of posts on one device when I’ve made some changes on the other device.

React Native’s ListView is built on ScrollView, which has an onRefreshStart prop. You pass it a function that accepts a callback as a param and calls the callback once you’re done refreshing (the callback tells the spinner it’s time to scoot).

This means the render function of the Posts Page component now looks like:

render() {
 var title = 'All Posts';
 if (this.props.filter) title = this.props.filter;
 return (
   <View style={styles.page}>
     <NavBar
       leftButton={this.backButton}
       title={title}
       rightButton={this.createButton}
     />
     <ListView
       automaticallyAdjustContentInsets={false}
       dataSource={this.state.posts}
       renderRow={post => (<Post post={post}
         nav={this.props.navigator}
         key={post.id}
       />)}
       onRefreshStart={(endRefreshing) => {
         PostActions.fetchUser(this.props.username);
         endRefreshing();
       }}
       style={styles.list}
     />
   </View>
 );
}

I also added a flux action to fetch the user’s data off the server:

fetchUser: function(username) {
 AppDispatcher.dispatch({
   actionType: 'fetch-user',
   username: username
 });
}

And in my Post Store:

function fetchUser(username) {
 var url = USER_URL + '/' + username;
 return fetch(url).then(res => res.json()).then((user) => {
   _users[username] = user;
   PostStore.emitChange();
 });
}
AppDispatcher.register(function(action) {
 case 'fetch-user':
   var username = action.username;
   if (!username) username = SettingStore.getUsername();
   fetchUser(username);
   break;
}

Note that this works when you’re viewing other user’s posts as well. This fixes #52.