useRefetchable
You can use useRefetchable when you want to fetch and re-render a fragment with different data:
Arguments:
They are the same as useFragment.
Return Value:
Object containing the following properties:
data
: Object that contains data which has been read out from the Relay store; the object matches the shape of specified fragment.error
: Error will be defined if an error has occurred while refetching the queryisLoading
: Boolean value which indicates if a refetch is currently in flight, including any incremental data payloads.refetch
: Function used to refetch the connection fragment with a potentially new set of variables.- Arguments:
variables
: Object containing the new set of variable values to be used to fetch the@refetchable
query.- These variables need to match GraphQL variables referenced inside the fragment.
- However, only the variables that are intended to change for the refetch request need to be specified; any variables referenced by the fragment that are omitted from this input will fall back to using the value specified in the original parent query. So for example, to refetch the fragment with the exact same variables as it was originally fetched, you can call
refetch({})
. - Similarly, passing an
id
value for the$id
variable is optional, unless the fragment wants to be refetched with a differentid
. When refetching a@refetchable
fragment, Relay will already know the id of the rendered object.
options
: [Optional] options objectfetchPolicy
: Determines if cached data should be used, and when to send a network request based on cached data that is available. See theuseQuery
section for full specification.onComplete
: Function that will be called whenever the refetch request has completed, including any incremental data payloads.
- Return value:
disposable
: Object containing adispose
function. Callingdisposable.dispose()
will cancel the refetch request.
- Behavior:
- Calling
refetch
with a new set of variables will fetch the fragment again with the newly provided variables. Note that the variables you need to provide are only the ones referenced inside the fragment. - Calling
refetch
will not cause the component to suspend. Instead, theisLoading
value will be set to true while the request is in flight
- Calling
- Arguments:
Behavior
- The component is automatically subscribed to updates to the fragment data: if the data for this particular
User
is updated anywhere in the app (e.g. via fetching new data, or mutating existing data), the component will automatically re-render with the latest updated data.
RefetchContainer
Differences with - A refetch query no longer needs to be specified in this api, since it will be automatically generated by Relay by using a
@refetchable
fragment. - Refetching no longer has a distinction between
refetchVariables
andrenderVariables
, which were previously vaguely defined concepts. Refetching will always correctly refetch and render the fragment with the variables you provide (any variables omitted in the input will fallback to using the original values from the parent query). - Refetching will unequivocally update the component, which was not always true when calling refetch from
RefetchContainer
(it would depend on what you were querying for in the refetch query and if your fragment was defined on the right object type).
import { useRefetchable, graphql } from 'relay-hooks';
const fragmentSpec = graphql`
fragment TodoList_user on User
@refetchable(queryName: "TodoListRefetchQuery") {
todos(
first: 2147483647 # max GraphQLInt
) @connection(key: "TodoList_todos") {
edges {
node {
id
complete
...Todo_todo
}
}
}
id
userId
totalCount
completedCount
...Todo_user
}
`;
const options = {
renderVariables: null,
observerOrCallback: () => { console.log('Refetch done') },
refetchOptions: {force: true},
}
const TodoApp = (props) => {
const { data: user, refetch } = useRefetchable(fragmentSpec, props.user);
const handlerRefetch = React.useCallback( () => refetch({}), [refetch]);
return (
<div>
<p> {user.id} </p>
<p> {user.userId} </p>
<p> {user.totalCount} </p>
<button onClick={handlerRefetch}> Refetch </button>
</div>
);
};
useRefetchableFragment (with suspense, like relay-experimental)
import { useRefetchableFragment } from 'relay-hooks';