Lots of this is just copied from the relay docs.
- relay.dev
- Example Graphql Schema used in many examples from the relay.dev docs
From https://relay.dev/docs/en/quick-start-guide#relay-environment
Before we can start rendering pixels on the screen, we need to configure Relay via a Relay Environment. The environment bundles together the configuration, cache storage, and network-handling that Relay needs in order to operate.
For the purposes of our example, we are simply going to configure our environment to communicate with our existing GraphQL server:
A Relay Environment requires at least a Store and a Network Layer. The above code uses the default implementation for Store, and creates a Network Layer using a simple fetchQuery function to fetch a GraphQL query from our server.
Usually we'd want a single environment in our app, so you could export this environment as a singleton instance from a module to make it accessible across your app.
import {
Environment,
Network,
RecordSource,
Store,
} from 'relay-runtime';
function fetchQuery(
operation,
variables,
) {
return fetch('/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: operation.text,
variables,
}),
}).then(response => {
return response.json();
});
}
const environment = new Environment({
network: Network.create(fetchQuery),
store: new Store(new RecordSource()),
});
export default environment;
Example QueryRenderer
with the whole tree right there (note props environment
, query
, variables
, render
):
// App.js
import React from 'react';
import {graphql, QueryRenderer} from 'react-relay';
const environment = /* defined or imported above... */;
export default class App extends React.Component {
render() {
return (
<QueryRenderer
environment={environment}
query={graphql`
query UserQuery {
viewer {
id
}
}
`}
variables={{}}
render={({error, props}) => {
if (error) {
return <div>Error!</div>;
}
if (!props) {
return <div>Loading...</div>;
}
return <div>User ID: {props.viewer.id}</div>;
}}
/>
);
}
}
Key takeaways:
- We have to name our queries and fragments according to conventions (relay compiler enforces this)
- The relay compiler will inspect your files for
graphql'query QueryName {}'
orgraphql'fragment FileName_propName'
tags and create accompanying__generated__/QueryName_prop.graphql
files. Their exports are used implicitly by babel, but we may import from their files to get generated type definitions example.
Reaction example for fragment Register_sale
export const RegisterFragmentContainer = createFragmentContainer(
trackPageViewWrapper(RegisterRoute),
{
sale: graphql`
fragment Register_sale on Sale {
id
}
`,
}
)
Accompanying autogenerated __generated__/Register_sale.graphql.ts
export type Register_sale$ref = typeof _Register_sale$ref;
export type Register_sale = {
readonly id: string;
readonly " $refType": Register_sale$ref;
};
const node: ConcreteFragment = {
"kind": "Fragment",
"name": "Register_sale",
"type": "Sale",
"metadata": null,
"argumentDefinitions": [],
"selections": [
{
"kind": "ScalarField",
"alias": null,
"name": "id",
"args": null,
"storageKey": null
},
{
"kind": "ScalarField",
"alias": null,
"name": "__id",
"args": null,
"storageKey": null
}
]
};
(node as any).hash = 'b82976437d651fac2989bd04d2c3253c';
export default node;