Skip to content

Instantly share code, notes, and snippets.

@erikdstock
Last active August 22, 2019 18:52
Show Gist options
  • Save erikdstock/cbe2bd3d9ef267edd548ca93d59c76f6 to your computer and use it in GitHub Desktop.
Save erikdstock/cbe2bd3d9ef267edd548ca93d59c76f6 to your computer and use it in GitHub Desktop.
Relay Notes

Relay notes.

Lots of this is just copied from the relay docs.

Helpful Sources:

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 {}' or graphql'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;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment