Relay: Better documentation about data-fetching and integration with React

Created on 3 Nov 2018  路  4Comments  路  Source: facebook/relay

TL;DR: Save newcomers headaches by explicitly stating that Relay is a data-fetching library in the docs intro and add a section to the docs that explains in detail how Relay integrates with React.


I want to start by stating that I'm relatively new to Relay but have been working with it intensively for the past couple of weeks. What's about to follow is based on my subjective opinions as single developer and they may based on incomplete understandings, so please take them with a grain of salt.

I've found that while I love Relay, I'm disappointed that it hasn't live up to my expectations. Part of my expectations were set up by misleading statements, some from well-known JS folks favorably comparing Relay as a replacement for other well-known JS libraries that manage state. But as I've come to learn (painfully), Relay isn't a state-management-cum-declarative-data-fetching-and-magical-component-state-and-prop-updating library, it's just a really well-thought-out data-fetching library.

Now, the Relay team isn't responsible for and doesn't have anything to do with misleading statements from unrelated people, but the wording of the intro only compounded my confusion and I wouldn't be surprised if other newcomers have been confused, too. From the intro:

Relay is a JavaScript framework for building data-driven React applications powered by GraphQL...Relay couples React with GraphQL and develops the idea of encapsulation further. It allows components to specify what data they need and the Relay framework provides the data.

Reading that, what I expected was a framework that will allow me to specify the data requirements for any component using GraphQL IDL and then will be _solely responsible_ for handling re-rendering and updates to those components whenever the data changes. Minimal dealing with props, no need to think about synchronizing data and variables across components, etc. When the graph updates, so should the components, just like when state or props update all the relevant components will update, magically. You just "specify what data [the components] need" and "the Relay framework provides the data," automatically updating all components that state a dependency on the updated part of the graph without any plumbing.

In my experience, however, Relay still requires you to do a lot of plumbing. For example, if you have a deeply nested component that requires, say, the exact same data from GraphQL as a component higher up in the hierarchy, you will need a chain of passed props all the way from QueryRenderer down to your deeply nested component. Even more complications arise when you have to think about sibling containers. I'm sure there are many other non-trivial examples that I haven't run into yet. Yet the intro continues:

This makes the data needs of inner components opaque and allows composition of those needs. Thinking about what data an app needs becomes localized to the component making it easier to reason about what fields are needed or no longer needed.

Data masking and declaring the data needs as fragments certainly helps to make those data needs opaque, but I'm still having to think a lot about how to pass that data around to make sure that all the components that state their data requirements in the IDL actually receive them. If I need to pass props all the way down from QueryRenderer, that doesn't feel very opaque to me as the programmer who has to think about details like what to name the props at each step of the way, the trade offs of having nested QueryRenderers that make some of my prop chains shorter but then create waterfalls, etc. Taken collectively, I end up having to reason about the data in a holistic rather than a componentized way.

IMHO, the only clear statement of what Relay actually is for is buried in the conclusion of the "Thinking in Relay" section:

Relay builds on this functionality to provide a framework for declarative data-fetching. (Emphasis in original.)

It's the data-fetching part that Relay makes componentized by encapsulating the declaration of each component's data needs, but Relay is fairly agnostic about how you manage that data once it's been fetched. I think that stating that upfront would save newcomers headaches. My suggestions:

  1. Make the data-fetching purpose of the framework front-and-center by replacing the intro sentence "Relay is a JavaScript framework for building data-driven React applications powered by GraphQL, designed from the ground up to be easy to use, extensible and, most of all, performant" with the following: "Relay is a JavaScript framework for declarative data-fetching that allows you to create React components that state their remote data needs using GraphQL fragments. It's designed from the ground up to be easy-to-use, extensible and, most of all, performant."

  2. Add a couple of sentences to the intro or possibly the Thinking in Relay section along the lines of: "In Relay, top-level components fetch the data specified within other components' GraphQL fragments and pass the data down the React hierarchy through props. Alternatively, you can synchronize and distribute the data fetched by Relay across your component hierarchy using React contexts, external state management libraries or any other method that you see fit. Relay is backed by its own internal store, but it's agnostic about your app's source of truth and state architecture. It's designed to be used primarily as a data-fetching tool."

  3. Create a section on how Relay integrates with React. I envision something like this: "In Relay, all data fetching is initiated using the QueryRenderer, refetch container or pagination container and here are the ways in which you initiate fetching. Here is what happens to your data once it's received from the wire. Here's how it gets stored in the Relay store and what that means--and what that doesn't mean. Here's how it gets exposed to your React components. And here are some patterns that we find useful for synchronizing/moving around your data once it's exposed to React."

docs wontfix

Most helpful comment

Hello @earksiinni, great topic!

At Entria we have a repository with few examples on how we use React Native + React Navigation + Relay Modern: https://github.com/entria/ReactNavigationRelayModern

Recently we did a PR opening lot's of best practices that helps us to scale our apps on production. You can check it here: https://github.com/entria/ReactNavigationRelayModern/pull/30

You can find us at React Brasil Slack channel for any help: http://react-brasil-slack.herokuapp.com/

All 4 comments

Hello @earksiinni, great topic!

At Entria we have a repository with few examples on how we use React Native + React Navigation + Relay Modern: https://github.com/entria/ReactNavigationRelayModern

Recently we did a PR opening lot's of best practices that helps us to scale our apps on production. You can check it here: https://github.com/entria/ReactNavigationRelayModern/pull/30

You can find us at React Brasil Slack channel for any help: http://react-brasil-slack.herokuapp.com/

@earksiinni thanks so much for the feedback here! I definitely think we can improve our messaging about what Relay is and the function it serves.

We're definitely planning to improve our messaging and docs, along with possible API improvements, and we would love to share with the community for feedback, so stay tuned for that.

We created some learning material to Relay Modern as a twitter thread https://twitter.com/sseraphini/status/1078595758801203202

feel free to add more links to it

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fedbalves picture fedbalves  路  3Comments

janicduplessis picture janicduplessis  路  3Comments

johntran picture johntran  路  3Comments

sibelius picture sibelius  路  3Comments

leebyron picture leebyron  路  3Comments