Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Data-fetching in React applications with Relay ...
Search
Marc-Andre Giroux
August 10, 2016
Programming
720
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Data-fetching in React applications with Relay & GraphQL
Marc-Andre Giroux
August 10, 2016
More Decks by Marc-Andre Giroux
See All by Marc-Andre Giroux
It Depends - Examining GraphQL Myths & Assumptions
xuorig
0
150
So you Want to Distribute your GraphQL Schema?
xuorig
4
880
So you Want to Distribute your GraphQL Schema?
xuorig
0
700
GraphQL Schema Design @ Scale
xuorig
5
2.2k
Continuous Evolution of GraphQL Schemas @ GitHub
xuorig
3
2.2k
GraphQL à Shopify
xuorig
0
300
Exploring GraphQL
xuorig
0
320
GraphQL @ Shopify
xuorig
6
1.8k
GraphQL on Rails
xuorig
2
410
Other Decks in Programming
See All in Programming
GraphQL の onError と Nullability のこれから
quramy
0
120
全ての永続トークンを、生まれる前に消し去りたい!
sylph01
2
1k
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
180
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
150
Workers Cache を知る
syumai
0
370
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
28
33k
Web Framework Benchmark Battle 2026, Any%
a_matsuda
2
2.6k
dotNET_vulnclicker_intro.pdf
deka_morita
0
150
Domain-Driven Transformation
hschwentner
2
2.3k
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
180
Rでドレミ/Do-Re-Mi_with_R
florets1
0
130
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
300
Featured
See All Featured
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
340
Visualization
eitanlees
153
17k
How to Ace a Technical Interview
jacobian
280
24k
Tell your own story through comics
letsgokoyo
1
1.1k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
330
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
[SF Ruby Conf 2025] Rails X
palkan
3
1.5k
The Spectacular Lies of Maps
axbom
PRO
1
1.1k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.4k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
3
3.9k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
Transcript
Data-fetching in React applications with Relay & GraphQL 1
A beautiful component 2
A beautiful simple component 3
React { <Shop> <Product> <ProductImage> 4
{ Shop component 5
Product component { 6
ProductImage component { 7
What if we needed to add a description? { 8
What kind of data is needed ? Shop Product Image
9
Let’s fetch that using reusable endpoints ? /shop/1 /products/1 /products/2
image/sabc images/def 10
Let’s fetch that using ad-hoc endpoints ? /shop_cart_page /shop_cart_page?include=images /shop_cart_page_with_images?num_images=2
/shop_cart_page_single_prices_and_descriptions_version1.2 /shop_cart_page_with_prices_and_descriptions_but_no_images 11 op_cart_page_with_prices_and_descriptions_and_images_but_only_one_300
12
GraphQL 13
query { myShop { name } } Simple query 14
Response { “myShop” { “name”: “My Kool Shop” } }
15
Query { myShop { name location { city address }
products(orderby: PRICE) { name price } } } 16
Response { “myShop” { “name”: “My Kool Shop”, “location”: {
“city”: “Montreal”, “address”: “5333 Avenue Casgrain”, }, “products”: [{ “name”: “A Chair”, “price”: 10000 }, { “name”: “A Table”, “price”: 20000 }] } } 17
Type System { myShop { name location { city address
} products(orderby: PRICE) { name price } } } type QueryRoot { myShop: Shop } 18
Type System enum ProductOrderEnum { PRICE, POPULARITY, ALPHABETICAL } type
Shop { name: String location: Address products(orderby: OrderEnum): [Product] } { { myShop { name location { city address } products(orderby: POPULARITY) { name price } } } 19
Type System type Address { city: String address: String }
{ { myShop { name location { city address } products(orderby: POPULARITY) { name price } } } 20
Type System type Product { name: String price: Int }
{ { myShop { name location { city address } products(orderby: POPULARITY) { name price } } } 21
Fragments { { myShop { name …locationFragment } } fragment
locationFragment on Shop { location { city address } } 22
Mutations { mutation { createProduct(name: “Kanye West Shoes”) { name
} } 23
How Relay can help { Relay React GraphQL 24
Query colocation { query Fragment Fragment Fragment Fragment 25
Query colocation { Shop Product Product Image 26
Relay Containers / Higher Order Components { Relay.createContainer(ShopComponent, { fragments:
{ … } }); Container Shop 27
Shop Component (Relay) { 28
Shop component (Relay) { 29
Product component (Relay) { 30
ProductImage component (Relay) { 31
How the *&^#@$ does that even work? { 32
Step 1: Making sense out of fragments { fragments: {
image: () => Relay.QL` fragment on Image { url } `, }, 33
Relay.QL (pre-transform) { fragments: { image: () => Relay.QL` fragment
on Image { url } `, }, 34
Relay.QL (transformed) { fragments: { image: function image() { return
function () { return { children: [{ fieldName: 'url', kind: 'Field', metadata: {}, type: 'String' }, { fieldName: 'id', kind: 'Field', metadata: { isGenerated: true, isRequisite: true }, type: 'ID' }], id: _reactRelay2.default.QL.__id(), kind: 'Fragment', metadata: {}, name: 'ProductImage_ImageRelayQL', type: 'Image' }; }(); } 35
Step 2: Query diff ( The Store ) { RelayRecord
Store • Client Side Cache • Normalized / Flattened Store 36
Step 2: Query diff { fragments: { product: () =>
Relay.QL` fragment on Product { name image { url } } `, }, 37
Step 2: Query diff { fragments: { product: () =>
Relay.QL` fragment on Product { name description image { url } } `, }, 38
Step 2: Query diff { fragments: { product: () =>
Relay.QL` fragment on Product { description } `, }, 39
Step 2: Query diff { fragments: { product: () =>
Relay.QL` fragment on Product { description } `, }, 40
Step 3: Split Deferred queries { fragments: { product: ()
=> Relay.QL` fragment on Product { name description ${Images.getFragment('product').defer()}} } `, }, 41
Step 3: Split Deferred queries { 42
Step 3: Split Deferred queries { 43
Step 4: Subtract in-flight queries { 44
Step 4: Subtract in-flight queries { 45
{ myShop { name location { city address } products(orderby:
PRICE) { name price } } } Final step: Printing { 46
Back to the Store { 47 Relay Record Store Cached
Records Queued Records
Mutations { class AddProductMutation extends Relay.Mutation { getMutation() { return
Relay.QL`mutation { addProduct }`; } getVariables() { return { productName: this.props.product.name }; } getFatQuery() { … } getConfigs() { … } getOptimisticResponse() { … } } 48
And so much more { 49 Subscriptions @stream Garbage collection
Server side rendering Connections
For more info: { 50 https://facebook.github.io/relay https://github.com/facebook/graphql
Thank you! Try it out yourself :) @__xuorig__ http://mgiroux.me xuorig
51