Reputation: 4539
I'm trying to find out how/if it is possible to trigger a refresh in a Relay Modern RefreshContainer
without passing (new) variables?
I’m looking for the best way to implement the good ol’ pull-to-refresh on a React Native list, that should simply refetch the original query - no variables needed?
According to docs (https://facebook.github.io/relay/docs/api-cheatsheet.html) this should be possible using
this.props.relay.refetch({}, callback, {force: true})
but I get an error saying "undefined is not an object ('evaluating taggedNode.modern')"
The query works just fine if I use a plain old FragmentContainer
instead, but I'd just like a simple pull-to-refresh functionality :-)
EDIT Adding more code for clarity. Also updated call to reflect change to API that includes render variables, passing null
class HistoryList extends React.PureComponent<void, Props, State> {
state = { refreshing: false };
_renderRow = ({ item }) => {
return <HistoryListItem item={item.node} />;
};
_renderHeader = ({ section }) => {
return (
<Text style={[cs.breadText, _styles.sectionHeader]}>
{section.title}
</Text>
);
};
_onRefresh = () => {
this.setState({ refreshing: true });
this.props.relay.refetch({}, null, this._onRefreshDone(), { force: true });
};
_onRefreshDone = () => {
this.setState({ refreshing: false });
};
_sortDataIntoSections = (edges: Array<Node>) => {
return _.chain(edges)
.groupBy(element => {
return moment(element.node.huntDate).format('MMMM YYYY');
})
.map((data, key) => {
return { title: key, data: data };
})
.value();
};
render() {
return (
<View style={_styles.container}>
<SectionList
renderSectionHeader={this._renderHeader}
sections={this._sortDataIntoSections(
this.props.entries.allJournalEntries.edges
)}
renderItem={this._renderRow}
keyExtractor={(item, index) => item.node.__id}
onRefresh={this._onRefresh}
refreshing={this.state.refreshing}
/>
</View>
);
}
}
export default createRefetchContainer(
HistoryList,
graphql`
fragment HistoryList_entries on Viewer {
allJournalEntries(orderBy: huntDate_DESC) {
count
edges {
node {
huntDate
...HistoryListItem_item
}
}
}
}
`
);
Upvotes: 0
Views: 1934
Reputation: 29
I have both solution applied (query for refetch and relay refetch call).
Refetch query (do not pay attention at fact, that I didn't specify a component for container, there is special decorator in our code base for it):
{
viewer: graphql`
fragment RatingSchoolsTableContainer_viewer on Viewer {
rating {
schools {
uid
masterUrl
paidOrderSum
paidOrderCount
averageReceipt
}
}
}
`,
},
graphql`
query RatingSchoolsTableContainer_RefetchQuery {
viewer {
...RatingSchoolsTableContainer_viewer
}
}
`,
And relay call:
this.props.relay?.refetch({}, null, () => {}, {force: true})
There is no re-render anyway, but I have new response from server in network.
Upvotes: 0
Reputation: 4539
A solution has been found by robrichard at github.
I was missing the third argument for the RefetchContainer
, which is the query to execute on refetch. This, combined with the suggestion from @zetavg was what was needed.
The exported module now looks like this:
export default createRefetchContainer(
HistoryList,
{
entries: graphql`
fragment HistoryList_entries on Viewer {
allJournalEntries(orderBy: huntDate_DESC) {
count
edges {
node {
huntDate
...HistoryListItem_item
}
}
}
}
`
},
graphql`
query HistoryListRefetchQuery {
viewer {
...HistoryList_entries
}
}
`
);
Upvotes: 2
Reputation: 318
It seems that the arguments of this.props.relay.refetch
has been change to refetch(refetchVariables, renderVariables, callback, options)
(in https://facebook.github.io/relay/docs/refetch-container.html) and the cheetsheet has been out-of-date.
I'm not sure that in which version that this has change, but you can give it a try and change your code to:
this.props.relay.refetch({}, null, callback, {force: true})
Upvotes: 2