How to Refetch Queries After Mutation in Relay?
- Dominant language
- Rust
- Stars
- 19k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
# Issue: How to Refetch Queries After Mutation in Relay?
I referred to the [Relay Docs - Refreshing Queries](https://relay.dev/docs/guided-tour/refetching/refetching-queries-with-different-data/#when-using-uselazyloadquery) for refreshing queries. However, I need clarification on how to refetch a query in the following use case where a mutation updates data, and the query needs to be refreshed afterward.
Below is the setup I'm working with:
### ListComponent
The `ListComponent` contains a `refresh` function that updates `queryOptions` to refetch the query with a new `fetchKey` and `fetchPolicy`.
```tsx
/**
* ListComponent.js
*/
const ListComponentQuery = require('__generated__/AppQuery.graphql');
function ListComponent(props: Props) {
const variables = {id: '4'};
const [refreshedQueryOptions, setRefreshedQueryOptions] = useState(null);
const refresh = useCallback(() => {
setRefreshedQueryOptions(prev => ({
fetchKey: (prev?.fetchKey ?? 0) + 1,
fetchPolicy: 'network-only',
}));
}, []);
return (
);
}
```
### MainContent
The MainContent uses useLazyLoadQuery to fetch data and renders it. The refresh function is called to refetch the query.
```tsx
/**
* MainContent.react.js
*/
function MainContent(props) {
const {refresh, queryOptions, variables} = props;
const data = useLazyLoadQuery(
graphql`
query AppQuery($id: ID!) {
user(id: $id) {
name
friends {
count
}
}
}
`,
variables,
queryOptions,
);
return (
<>
{data.user?.name}
refresh()}>
Fetch latest count
);
}
```
### CreateItemButton
I want to perform a mutation and then refresh the query in ListComponent. Here's an example mutation setup:
```tsx
/**
* CreateItemButton.react.js
*/
function CreateItemButton({refresh}) {
const [commitMutation] = useMutation(
graphql`
mutation CreateItemMutation($input: CreateItemInput!) {
createItem(input: $input) {
item {
id
name
}
user {
id
friends {
count
}
}
}
}
`,
);
const handleCreateItem = () => {
commitMutation({
variables: {
input: { /* mutation input */ },
},
onCompleted: () => {
// Refresh the query after the mutation completes
// HOW CAN I DO THIS?
refresh();
},
onError: (error) => {
console.error(error);
},
});
};
return (
Create Item
);
}
```
And I’m curious about how to handle the case when this Button is not a child node of ListComponent but is at the same level or a parent node.
### Question
How can I effectively refresh the query after the mutation in this setup? Specifically:
Is useLazyLoadQuery the best approach here, or should I use another API like useFragment or useRefetchableFragment?
Is there a better pattern to refetch queries post-mutation in Relay?
I appreciate any guidance or best practices for handling this scenario.
Contributor guide
Assessment
This issue has not been assessed yet.