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
usePagination doesn't update state #96
Comments
Hi @nibblesnbits can you give me more info by doing some debugging in the store and here? |
When I call But I also had a break point on that line and it was never hit. Line 205 was executed and I grabbed this from {
"data": {
"appUserId": 0,
"list": {
"totalCount": 38,
"edges": [
{
"node": {
"activityId": 6,
"name": "Virtual Drinks",
"shortDescription": "Whether it's coffee break or happy hour, grab the beverage of your choice for a chemically-enhanced video chat.",
"activityUrl": "https://www.nytimes.com/2020/03/20/well/virus-virtual-happy-hour.html",
"imageUrl": "https://uploads-ssl.webflow.com/5e576c2ceb561c252e1d2e2d/5ec6e38e3e71f1a96e78f940_min-virtual%20coffee.jpg",
"isApproved": true,
"__typename": "Activity"
},
"cursor": "Ng=="
},
{
"node": {
"activityId": 7,
"name": "Cook Mexican Street Tacos with a Pro Chef",
"shortDescription": "Immerse yourself in Mexico's extraordinary street food culture in a guided cooking class with a professional chef.",
"activityUrl": "https://www.airbnb.com/experiences/1661135?source=p2",
"imageUrl": "https://a0.muscache.com/im/pictures/ec6a9398-1ed3-400a-8f97-ee3e7eeed6dd.jpg?aki_policy=exp_md",
"isApproved": true,
"__typename": "Activity"
},
"cursor": "Nw=="
},
{
"node": {
"activityId": 8,
"name": "Meet My Bees",
"shortDescription": "Open a beehive with a fourth-generation beekeeper to see these amazing creatures building honeycombs, making honey, and working together.",
"activityUrl": "https://www.airbnb.com/experiences/1675237?source=p2",
"imageUrl": "https://a0.muscache.com/im/pictures/80add1a5-f051-4aea-a7ee-f5b4491d3346.jpg?aki_policy=exp_md",
"isApproved": true,
"__typename": "Activity"
},
"cursor": "OA=="
},
{
"node": {
"activityId": 9,
"name": "Mobile Photo Secrets with a Nat Geo Winner",
"shortDescription": "Learn the secrets of taking amazing photos with your phone with examples from beautiful Barcelona.",
"activityUrl": "https://www.airbnb.com/experiences/1718920?source=p2",
"imageUrl": "https://a0.muscache.com/im/pictures/lombard/MtTemplate-1718920-media_library/original/b211f9ca-0154-4b7f-9fb3-76757298119e.jpeg?aki_policy=exp_md",
"isApproved": true,
"__typename": "Activity"
},
"cursor": "OQ=="
},
{
"node": {
"activityId": 10,
"name": "Draw from Within with a New York Artist",
"shortDescription": "Re-connect, re-imagine & relax through the restorative power of the creative process.",
"activityUrl": "https://www.airbnb.com/experiences/1655361?source=p2",
"imageUrl": "https://a0.muscache.com/im/pictures/lombard/MtTemplate-1655361-media_library/original/5d1c7ca9-8397-4884-91c1-c5eb0fea7dff.jpg?aki_policy=exp_md",
"isApproved": true,
"__typename": "Activity"
},
"cursor": "MTA="
}
],
"pageInfo": {
"endCursor": "MTA=",
"hasNextPage": true,
"startCursor": "Ng==",
"hasPreviousPage": false
}
}
},
"isMissingData": false,
"seenRecords": {
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer",
"__typename": "AppUser",
"appUserId": 0,
"firstName": "Anonymous",
"lastName": null,
"unviewedActivities(first:5)": {
"__ref": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5)"
},
"__UnviewedActivities_list_connection": {
"__ref": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection"
}
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection",
"__typename": "UnviewedActivitiesConnection",
"__connection_next_edge_index": 5,
"totalCount": 38,
"edges": {
"__refs": [
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:0",
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:1",
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:2",
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:3",
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:4"
]
},
"pageInfo": {
"__ref": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:pageInfo"
}
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:0": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:0",
"__typename": "UnviewedActivitiesConnectionEdge",
"node": {
"__ref": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:0:node"
},
"cursor": "Ng=="
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:0:node": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:0:node",
"__typename": "Activity",
"activityId": 6,
"name": "Virtual Drinks",
"shortDescription": "Whether it's coffee break or happy hour, grab the beverage of your choice for a chemically-enhanced video chat.",
"activityUrl": "https://www.nytimes.com/2020/03/20/well/virus-virtual-happy-hour.html",
"imageUrl": "https://uploads-ssl.webflow.com/5e576c2ceb561c252e1d2e2d/5ec6e38e3e71f1a96e78f940_min-virtual%20coffee.jpg",
"isApproved": true
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:1": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:1",
"__typename": "UnviewedActivitiesConnectionEdge",
"node": {
"__ref": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:1:node"
},
"cursor": "Nw=="
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:1:node": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:1:node",
"__typename": "Activity",
"activityId": 7,
"name": "Cook Mexican Street Tacos with a Pro Chef",
"shortDescription": "Immerse yourself in Mexico's extraordinary street food culture in a guided cooking class with a professional chef.",
"activityUrl": "https://www.airbnb.com/experiences/1661135?source=p2",
"imageUrl": "https://a0.muscache.com/im/pictures/ec6a9398-1ed3-400a-8f97-ee3e7eeed6dd.jpg?aki_policy=exp_md",
"isApproved": true
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:2": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:2",
"__typename": "UnviewedActivitiesConnectionEdge",
"node": {
"__ref": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:2:node"
},
"cursor": "OA=="
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:2:node": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:2:node",
"__typename": "Activity",
"activityId": 8,
"name": "Meet My Bees",
"shortDescription": "Open a beehive with a fourth-generation beekeeper to see these amazing creatures building honeycombs, making honey, and working together.",
"activityUrl": "https://www.airbnb.com/experiences/1675237?source=p2",
"imageUrl": "https://a0.muscache.com/im/pictures/80add1a5-f051-4aea-a7ee-f5b4491d3346.jpg?aki_policy=exp_md",
"isApproved": true
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:3": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:3",
"__typename": "UnviewedActivitiesConnectionEdge",
"node": {
"__ref": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:3:node"
},
"cursor": "OQ=="
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:3:node": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:3:node",
"__typename": "Activity",
"activityId": 9,
"name": "Mobile Photo Secrets with a Nat Geo Winner",
"shortDescription": "Learn the secrets of taking amazing photos with your phone with examples from beautiful Barcelona.",
"activityUrl": "https://www.airbnb.com/experiences/1718920?source=p2",
"imageUrl": "https://a0.muscache.com/im/pictures/lombard/MtTemplate-1718920-media_library/original/b211f9ca-0154-4b7f-9fb3-76757298119e.jpeg?aki_policy=exp_md",
"isApproved": true
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:4": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:edges:4",
"__typename": "UnviewedActivitiesConnectionEdge",
"node": {
"__ref": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:4:node"
},
"cursor": "MTA="
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:4:node": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:unviewedActivities(first:5):edges:4:node",
"__typename": "Activity",
"activityId": 10,
"name": "Draw from Within with a New York Artist",
"shortDescription": "Re-connect, re-imagine & relax through the restorative power of the creative process.",
"activityUrl": "https://www.airbnb.com/experiences/1655361?source=p2",
"imageUrl": "https://a0.muscache.com/im/pictures/lombard/MtTemplate-1655361-media_library/original/5d1c7ca9-8397-4884-91c1-c5eb0fea7dff.jpg?aki_policy=exp_md",
"isApproved": true
},
"client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:pageInfo": {
"__id": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer:__UnviewedActivities_list_connection:pageInfo",
"__typename": "PageInfo",
"hasNextPage": true,
"hasPreviousPage": false,
"endCursor": "MTA=",
"startCursor": "Ng=="
}
},
"selector": {
"kind": "SingularReaderSelector",
"dataID": "client:root:authInfo(redirectUri:\"http://localhost:3000/login\",source:\"google\"):viewer",
"node": {
"argumentDefinitions": [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "cursor",
"type": "ID"
},
{
"defaultValue": 5,
"kind": "LocalArgument",
"name": "count",
"type": "Int!"
}
],
"kind": "Fragment",
"metadata": {
"connection": [
{
"count": "count",
"cursor": "cursor",
"direction": "forward",
"path": ["list"]
}
]
},
"name": "UnviewedActivities_user",
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "appUserId",
"storageKey": null
},
{
"alias": "list",
"args": null,
"concreteType": "UnviewedActivitiesConnection",
"kind": "LinkedField",
"name": "__UnviewedActivities_list_connection",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "totalCount",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "UnviewedActivitiesConnectionEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Activity",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "activityId",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "shortDescription",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "activityUrl",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "imageUrl",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "isApproved",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cursor",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "PageInfo",
"kind": "LinkedField",
"name": "pageInfo",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "endCursor",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasNextPage",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "startCursor",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasPreviousPage",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"type": "AppUser",
"hash": "e1164886b2d41be49df16b84abc3c0cf"
},
"variables": {
"appUserId": 0,
"count": 10,
"cursor": null,
"redirectUri": "http://localhost:3000/login",
"source": "google"
},
"owner": {
"identifier": "query UnviewedActivitiesRefetchQuery( $appUserId: Int! $count: Int! $cursor: ID) { user(id: $appUserId) { ...UnviewedActivities_user_1G22uz }}fragment UnviewedActivities_user_1G22uz on AppUser { appUserId list: unviewedActivities(first: $count, after: $cursor) { totalCount edges { node { activityId name shortDescription activityUrl imageUrl isApproved __typename } cursor } pageInfo { endCursor hasNextPage startCursor hasPreviousPage } }}{\"appUserId\":0,\"count\":10,\"cursor\":null,\"redirectUri\":\"http://localhost:3000/login\",\"source\":\"google\"}",
"node": {
"fragment": {
"argumentDefinitions": [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "appUserId",
"type": "Int!"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "count",
"type": "Int!"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "cursor",
"type": "ID"
}
],
"kind": "Fragment",
"metadata": null,
"name": "UnviewedActivitiesRefetchQuery",
"selections": [
{
"alias": null,
"args": [
{
"kind": "Variable",
"name": "id",
"variableName": "appUserId"
}
],
"concreteType": "AppUser",
"kind": "LinkedField",
"name": "user",
"plural": false,
"selections": [
{
"args": [
{
"kind": "Variable",
"name": "count",
"variableName": "count"
},
{
"kind": "Variable",
"name": "cursor",
"variableName": "cursor"
}
],
"kind": "FragmentSpread",
"name": "UnviewedActivities_user"
}
],
"storageKey": null
}
],
"type": "RootQueryType"
},
"kind": "Request",
"operation": {
"argumentDefinitions": [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "appUserId",
"type": "Int!"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "count",
"type": "Int!"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "cursor",
"type": "ID"
}
],
"kind": "Operation",
"name": "UnviewedActivitiesRefetchQuery",
"selections": [
{
"alias": null,
"args": [
{
"kind": "Variable",
"name": "id",
"variableName": "appUserId"
}
],
"concreteType": "AppUser",
"kind": "LinkedField",
"name": "user",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "appUserId",
"storageKey": null
},
{
"alias": "list",
"args": [
{
"kind": "Variable",
"name": "after",
"variableName": "cursor"
},
{
"kind": "Variable",
"name": "first",
"variableName": "count"
}
],
"concreteType": "UnviewedActivitiesConnection",
"kind": "LinkedField",
"name": "unviewedActivities",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "totalCount",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "UnviewedActivitiesConnectionEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Activity",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "activityId",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "shortDescription",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "activityUrl",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "imageUrl",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "isApproved",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cursor",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "PageInfo",
"kind": "LinkedField",
"name": "pageInfo",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "endCursor",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasNextPage",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "startCursor",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasPreviousPage",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
},
{
"alias": "list",
"args": [
{
"kind": "Variable",
"name": "after",
"variableName": "cursor"
},
{
"kind": "Variable",
"name": "first",
"variableName": "count"
}
],
"filters": null,
"handle": "connection",
"key": "UnviewedActivities_list",
"kind": "LinkedHandle",
"name": "unviewedActivities"
}
],
"storageKey": null
}
]
},
"params": {
"id": null,
"metadata": {},
"name": "UnviewedActivitiesRefetchQuery",
"operationKind": "query",
"text": "query UnviewedActivitiesRefetchQuery( $appUserId: Int! $count: Int! $cursor: ID) { user(id: $appUserId) { ...UnviewedActivities_user_1G22uz }}fragment UnviewedActivities_user_1G22uz on AppUser { appUserId list: unviewedActivities(first: $count, after: $cursor) { totalCount edges { node { activityId name shortDescription activityUrl imageUrl isApproved __typename } cursor } pageInfo { endCursor hasNextPage startCursor hasPreviousPage } }}"
},
"hash": "555ab7868d36d6356ff2a4e06048da12"
},
"variables": {
"appUserId": 0,
"count": 10,
"cursor": null,
"redirectUri": "http://localhost:3000/login",
"source": "google"
}
}
}
} The screenshot is the data I was expecting to be rendered. |
I did notice tonight that in https://github.com/relay-tools/relay-hooks/blob/master/src/FragmentResolver.ts#L404, we call There's a couple obvious things to note here.
Am I at all on the right track? I'm working on finding a way to debug this in the actual TypeScript ( |
@nibblesnbits, reading your code it seems that the problem was the difference between the two queries executed. This function is called by relay when there is an update of the store to notify all the fragments / queries subscribed |
I've updated the code to use a refetch, and ensured the queries match, but still no dice. In this case I'm simply asking for a larger result set, but I see the same result. import PropTypes from "prop-types";
import React from "react";
import { ReactRelayContext, createFragmentContainer } from "react-relay";
import { graphql } from "babel-plugin-relay/macro";
import UnviewedActivities from "./UnviewedActivities";
import { Container, Typography } from "@material-ui/core";
const propTypes = {
authInfo: PropTypes.object.isRequired,
relay: PropTypes.object.isRequired,
};
const contextType = ReactRelayContext;
class Activities extends React.Component {
render() {
const { authInfo } = this.props;
if (!authInfo) {
return <div>Loading...</div>;
}
return (
<Container>
<Typography variant="h6">
Welcome to my app! Select some activities to get started.
</Typography>
<UnviewedActivities authInfo={authInfo} />
</Container>
);
}
}
Activities.propTypes = propTypes;
Activities.contextType = contextType;
export default createFragmentContainer(Activities, {
authInfo: graphql`
fragment Activities_authInfo on AuthInfo {
...UnviewedActivities_authInfo
}
`,
}); import PropTypes from "prop-types";
import React, { useState, useEffect } from "react";
import { graphql } from "babel-plugin-relay/macro";
import ActivityCard from "./ActivityCard";
import { Grid, Button } from "@material-ui/core";
import { useRefetch } from "relay-hooks";
const propTypes = {
authInfo: PropTypes.object.isRequired,
};
const fragmentSpec = graphql`
fragment UnviewedActivities_authInfo on AuthInfo
@argumentDefinitions(
cursor: { type: "ID" }
count: { type: "Int!", defaultValue: 5 }
) {
viewer {
appUserId
list: unviewedActivities(first: $count, after: $cursor)
@connection(key: "UnviewedActivities_list") {
edges {
node {
activityId
name
shortDescription
activityUrl
imageUrl
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
}
}
`;
const connectionConfig = {
direction: "forward",
query: graphql`
query UnviewedActivitiesRefetchQuery($count: Int!, $cursor: ID) {
authInfo {
...UnviewedActivities_authInfo
@arguments(cursor: $cursor, count: $count)
}
}
`,
getConnectionFromProps(props) {
return props.list;
},
getFragmentVariables(previousVariables, totalCount) {
return {
...previousVariables,
count: totalCount,
};
},
getVariables({ list }, { count, cursor }) {
return {
count,
cursor: list.pageInfo.endCursor,
};
},
};
const UnviewedActivities = (props) => {
const [authInfo, refetch] = useRefetch(fragmentSpec, props.authInfo);
const [, setLoads] = useState(0);
const [selected, setSelected] = useState([]);
const {
viewer: {
list: { edges },
},
} = authInfo;
useEffect(() => {
const key = "app:selectedActivities";
const item = localStorage.getItem(key);
if (item) {
setSelected(JSON.parse(item));
} else {
localStorage.setItem(key, JSON.stringify([]));
}
}, []);
const loadNextPage = () => {
// if (!hasMore() || isLoading()) {
// return;
// }
refetch(
connectionConfig.query,
{ count: 10 },
null,
() => {
setLoads((v) => v + 1);
console.log("loaded more");
},
{
force: true,
}
);
};
const addActivity = (id, pass) => {
const key = "app:selectedActivities";
const stored = localStorage.getItem(key) || [];
const parsed = stored instanceof Array ? stored : JSON.parse(stored);
const selected = [...parsed, { id, pass }];
localStorage.setItem(key, JSON.stringify(selected));
setSelected(selected);
const remaining = edges.filter(
({ node: a }) => !selected.some((s) => s.id === a.activityId)
);
if (remaining.length === 1) {
loadNextPage();
}
};
const remaining = edges.filter(
({ node: a }) => !selected.some((s) => s.id === a.activityId)
);
return (
<>
<Button onClick={() => loadNextPage()}>Load More</Button>
<Grid
container
direction="row"
justify="center"
alignItems="center"
spacing={2}
>
{remaining.map(({ node: activity }) => (
<Grid item key={activity.activityId}>
<ActivityCard {...activity} addActivity={addActivity} />
</Grid>
))}
</Grid>
</>
);
};
UnviewedActivities.propTypes = propTypes;
export default UnviewedActivities;
|
In this function you can see the relay logics of fragment update notification. Here you can find all the tests that are performed for usePagination The refetch/loadMore appears to execute a different query than the one the fragment was subscribed to. Could you send me the response of the query and the response of the refetch (you can avoid including all the edges). |
First response: {
"data": {
"authInfo": {
"viewer": {
"appUserId": 0,
"list": {
"edges": [
// ...
],
"pageInfo": { "endCursor": "MTA=", "hasNextPage": true }
}
}
}
}
} Second response: {
"data": {
"authInfo": {
"viewer": {
"appUserId": 0,
"list": {
"edges": [
// ...
],
"pageInfo": { "endCursor": "MTU=", "hasNextPage": true }
}
}
}
}
} |
have you tried debugging In this function? |
even better if you can create a minimal example project on github so that i can investigate the error |
The fragment is not updated by the Relay store because the query is performed with different parameters. This for Relay is as if a different query had been executed. to work it is necessary to modify fetchQuery in UnviewedActivities.js
|
That works! But there's one new problem. It's pulling in the new data, but only appending the data, not replacing the entire result set with the new edges. Is this intended? Pull on the repo to get what I mean. |
yes, this is its behavior. |
the default behavior of check the connection handler code, you can modify it to your will |
My problem is solved! I guess it was never a bug to begin with. Sorry! 🙏 |
My Components:
My Problem:
Upon a successful call to
loadMore()
, the fetch is made and I see the correct new set of data in my dev tools Network tab, but theuser
value returned fromusePagination()
is not updated. Even if I force a rerender withsetLoads((v) => v + 1);
, theuser
value has not been updated.My Setup:
The text was updated successfully, but these errors were encountered: