Relay modern. Refetch container usage.

Relay modern is an awesome library but it has one lack — documentation.

In this short article I will try to explain and show how it works and how to use it.


We start from am example: let’s say we have a root value called viewer also we have query called users with type [User] and we have User type with id, name, company, DOB fields. The query lets us find a user by company. Let’s write a query which fetches users who has “MyCompany” in company field.

In out UsersList component:

const UsersList = props => (
<div>{props.users.length}</div>
);
<QueryRenderer
query={graphql`
UsersListQuery($company: String) {
users(company: $company) {
id
name
}
}`
}
variables={{company: 'MyCompany'}}
environment={myEnvironment}
render={({ error, props ) => <UsersList users={props.data} />}
/>

This is how fetching and displaying data usually looks. It might looks a bit differently from what you have but it should be pretty similar.

We fetch all users who has MyCompany in company field and it’s ok. But what if we want to fetch users who has another company in the company field? This is what refetchContainer what made for.

We need to add one more HOC to our UsersList component.

const UsersList = (props) => (
<div>
<span>{users.length}</span>
<button
onClick={() => props.relay.refetch((prev) => ({ company: 'NotMyCompany' }))}
>
Load users with NotMyCompany
</button>
<div>
);
const RefetchableUsersList = createRefetchContainer(
UsersList,
{
users: graphql.experimental`
fragment UsersList_users on User
@argumentDefinitions(
company: { type: String }
) {
id
name
}
`
},
graphql.experimental`
query UsersListRefetchQuery($company: String) {
users(company: $company) {
...UsersList_users @arguments(company: $company)
}
}
`
);
<QueryRenderer
query={graphql`
UsersListQuery{
users {
...UsersList_users
}
}`
}
variables={{company: 'MyCompany'}}
environment={myEnvironment}
render={({ error, props ) => <RefetchableUsersList users={props.data} />}
/>

Now let’s take a look at each item in the code: UsersList component now has another prop called relay. Relay has method refetch which takes a function(or a bag of variables) which returns a new set of variables. Once we click this button a request with variable company: NotMyCompany will be sent. It also takes these arguments:

refetchVariables: Variables | ((fragmentVariables: Variables) => Variables),
renderVariables: ?Variables,
callback: ?(error: ?Error) => void,
options?: RefetchOptions,

createRefetchContainer is a tool which allows us to change a variable and fetch another set of data from the server. It takes:

  1. Component. React component where relay props will be passed.
  2. Fragments. Object of fragments. The caveats there is that a key in this object should be the same as your query name, otherwise relay would not pass data to your component.
  3. TaggedNode. The query itself. It’s basically a query which would be invoked whenever refetch function is called.

As you might have noticed it’s too much code. Probably you will find useful this library https://github.com/ErrorPro/relay-compose

This is a basic usage. Notice that this feature still in experimental stage it means that it might be changed in the future. I don’t provide a demo right now but if this post would be helpful for some people I will create one and update this post. Like and share ;)

Some links:

Working example: https://github.com/ErrorPro/relay-modern-hello-world/commit/94548f22ad1d31bc21ae7874470151ed2824fd43