Search code examples
react-nativerelayjsrelay

Relay Modern, Load More is not working, hasMore() keep returning false


i'm currently working on RN using expo, the list just initially fine, until i follow the loadMore tutorial, load more is not working, the hasMore() function returning false, whereas my hasNextPage is true

my home screen has a record list inside it

this is my home

import Expo from 'expo';
import React, {Component} from 'react';
import {
  View,
  Text,
  ActivityIndicator,
  FlatList,
  TouchableOpacity
} from 'react-native';

import {
  Button
} from 'react-native-elements';

import {
  QueryRenderer,
  createPaginationContainer,
  graphql
} from 'react-relay';

import environment from '../createRelayEnvironment';
import DummyList from '../component/dummyList';

class Home extends Component {

  render() {
    return(
      <QueryRenderer
        environment={environment}
        query={graphql`
          query homeQuery(
            $count: Int!
            $cursor: String!
          ) {
            viewer {
              ...dummyList_viewer
            }
          }
        `}
        variables= {{
            count: 5,
            cursor: ''
          }
        }
        render={({error, props, retry}) => {
          if(props){
            return(
              <DummyList {...props} />
            );
          }

          return(
            <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
              <ActivityIndicator size="large" />
            </View>
          );
        }}
      />
    );
  }
}

export default Home;

this is my inner list child component

```

import Expo from 'expo';
import React, {Component} from 'react';
import {
  View,
  Text,
  FlatList,
  TouchableOpacity
} from 'react-native';

import {
  createPaginationContainer,
  graphql
} from 'react-relay';

class DummyList extends Component {
  renderItem(item) {
    return(
      <View style={{padding: 10}}>
        <Text key={item.node.id}>{item.node.title}</Text>
      </View>
    );
  }

  _loadMore() {
    console.log('this.props.relay.hasMore()', this.props.relay.hasMore());
    if(!this.props.relay.hasMore() || this.props.relay.isLoading()){
      return;
    }

    this.props.relay.loadMore(
      10,
      e => {
        console.log('e', e);
      }
    )
  }

  render() {
    console.log('apa aja nih props-nya', this.props);
    return(
      <View>
        <FlatList
          data={this.props.viewer.allDummies.edges}
          renderItem={({item}) => this.renderItem(item)}
          keyExtractor={(item, index) => item.node.id}
        />
        <TouchableOpacity style={{padding: 10}} onPress={() => this._loadMore()}>
          <Text>Load More</Text>
        </TouchableOpacity>
      </View>
    )
  }
}

export default createPaginationContainer(
  DummyList,
  {
    viewer: graphql`
      fragment dummyList_viewer on viewer {
        allDummies(first: $count, after: $cursor) @connection(key: "DummyList_allDummies"){
          pageInfo{
            hasNextPage
          }
          edges{
            cursor
            node {
              id
              title
            }
          }
        }
      }
    `
  },
  {
    direction: 'forward',
    getConnectionFromProps(props) {
      console.log('getConnectionFromProps props', props);
      return props.viewer;
      // return props.user && props.user.feed;
    },
    getFragmentVariables(prevVars, totalCount) {
      return {
        ...prevVars,
        count: totalCount
      }
    },
    getVariables(props, { count, cursor }, fragmentVariables) {
      return {
        count,
        cursor
      }
    },
    query: graphql`
      query dummyListQuery(
        $count: Int!
        $cursor: String
      ){
        viewer{
          ...dummyList_viewer
        }
      }
    `
  }
);

```

i couldn't find the reason why my hasMore() keep returning false, i have 1000 records FYI, and initially load 5

capture_1


Solution

  • I had the same problem, this.props.relay.hasMore() always returning false. I explicitly added to the query all the pageInfo and now is returning true as it should.

    pageInfo {
      endCursor
      hasNextPage
      hasPreviousPage
      startCursor
    }
    

    Too bad the docs are not accurate or are out of sync with the implementation. Moreover, I noticed that without adding pageInfo to the fragment, the query sent to the server did include pageInfo fields so this issue perhaps is a BUG in the pagination container.