Nativebase: RefreshControl on List doesn't work on iOS

Created on 20 Jul 2018  路  8Comments  路  Source: GeekyAnts/NativeBase

We have this Contacts component for displaying a refreshable list of contacts.

import React, { Component } from 'react';
import { RefreshControl } from 'react-native';
import { connect } from 'react-redux';
import { Button, Container, Content, Icon, List, Spinner } from 'native-base';
import PropTypes from 'prop-types';
import { cloneDeep } from 'lodash';
import { fetchAll } from '../../actions/contacts';
import { navigateToConversation } from '../../actions/conversations';
import ContactListItem from './ContactListItem';

class Contacts extends Component {
  static propTypes = {
    contacts: PropTypes.arrayOf(PropTypes.shape({
      id: PropTypes.string.isRequired,
    })).isRequired,
    fetched: PropTypes.bool.isRequired,
    handleConfirm: PropTypes.func.isRequired,
    handleRefresh: PropTypes.func.isRequired,
    refreshing: PropTypes.bool.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = { contacts: cloneDeep(this.props.contacts) };
    this.onSelect = this.onSelect.bind(this);
  }

  onSelect(contactId) {
    const updatedContacts = this.state.contacts.map(contact => (
      contact.id === contactId
        ? { ...contact, selected: !contact.selected }
        : contact
    ));
    this.setState({ contacts: updatedContacts });
  }

  render() {
    const {
      fetched, handleConfirm, handleRefresh, refreshing,
    } = this.props;
    const { contacts } = this.state;
    const selectedContacts = contacts.filter(({ selected }) => selected);
    return (
      <Container>
        <Content>
          {
            selectedContacts.length
              ? (
                <Button onPress={() => handleConfirm(selectedContacts)}>
                  <Icon android="md-exit" ios="ios-exit" name="plane" />
                </Button>
              )
              : null
          }
          {!fetched && refreshing && <Spinner />}
          <List
            dataArray={contacts}
            refreshControl={
              <RefreshControl
                onRefresh={handleRefresh}
                refreshing={refreshing}
              />
            }
            renderRow={contact => (<ContactListItem
              {...contact}
              key={contact.id}
              onPress={() => this.onSelect(contact.id)}
            />)}
          />
        </Content>
      </Container>
    );
  }
}

export default connect(
  state => ({
    contacts: state.contacts.list,
    fetched: state.contacts.fetched,
    refreshing: state.contacts.fetching,
  }),
  dispatch => ({
    handleRefresh: () => dispatch(fetchAll(true)),
    handleConfirm: contacts => dispatch(navigateToConversation(contacts)),
  }),
)(Contacts);

We are able to refresh the list on Android but not on iOS.

node, npm, react-native, react and native-base version

node 10.7.0
yarn 1.7.0
react-native 0.55.4
react 16.3.1
native-base 2.6.1

Expected behaviour

Both on Android and iOS it should trigger the handleRefresh function and displaying the spinner
until refreshing becomes false again.

Actual behaviour

It works as expected on Android, but not on iOS.

Steps to reproduce should include code snippet and screenshot

Component above.

Is the bug present in both iOS and Android or in any one of them?

Just iOS.

Any other additional info which would help us debug the issue quicker.

None.

invalid

All 8 comments

I have the exact same issue. Only significant difference between our code is that my RefreshControl is associate to the Content block.

_onRefresh is never called on IoS whereas it works fine on Android.

                <Content style={Styles.content}
                    refreshControl={
                        <RefreshControl
                            refreshing={this.state.refreshing}
                            onRefresh={this._onRefresh}
                        />
                    }
                >

_onRefresh = () => {
    console.log('refreshing home...')
    this.setState({ refreshing: true })
    this.loadAssets()
}

loadAssets = () => {
    //console.log("this.loadAssets");
    this.props.fetchAssets(this.props)
    this.setState({ refreshing: false })
}

Any news about this issue?

Any news about this issue?

@EgidioCaprino It is mentioned in Docs, that not to use NativeBase List, instead use FlatList

@hoekma Example provided in #1720 works fine, cross checked it
https://github.com/GeekyAnts/NativeBase/issues/1720#issuecomment-376062502

Closing this, since usage of List is discouraged

Thank you @SupriyaKalghatgi. Removed padding from style of and it works fine now!

Thank you @SupriyaKalghatgi

Was this page helpful?
0 / 5 - 0 ratings