SlideShare a Scribd company logo
Taming
The Beast
How to tame React
& GraphQL
^(One error at a time)
Susanna Wong
@studioswong
Meet Cerberus. Cerberus	kept	perpetual	watch at	the	
gates,	preventing	the	living	from	
entering	and	the	dead	from leaving.
Taming the beast - how to tame React & GraphQL, one error at a time
|
Lets tame some
errors!
Step 1:
Setting up the
Query
query ($topics: String $offset: Int) {
Ceberus(
section: "most-popular"
rows: 4
start: $offset
type: "gallery"
topicLabel: $topics
) {
results
docs {
... on popularGallery {
title
type
topics {
label
}
imageLink
}
}
}
}
Query.gql
Step 2:
Exporting the
query and
importing into
React Component
graphql/index.js
component/index.js
export galleryQuery from './Query.gql';
import { galleryQuery } from './graphql';
Step 3:
Construct
functions for
fetching Query
within component
component/index.js
async fetchQuery(client, query, topics, offset)
{
const data = await client.query({
query,
variables: {
topics: topics.join(';'),
offset
}
});
return data
}
async fetchData() {
const { client, topics } = this.props;
const galleries = await this.fetchQuery(
client, galleryQuery, topics, galleryStart);
… // stuff that processes the galleries data
this.setState({
// update state with latest data});
}
query ($topics: String $offset: Int) {
Ceberus(
section: "most-popular"
rows: 4
start: $offset
type: "gallery"
topicLabel: $topics
) {
results
docs {
... on popularGallery {
title
type
topics {
label
}
imageLink
}
}
}
}
Query.gql graphql/index.js
export galleryQuery from './Query.gql';
component/index.js
async fetchQuery(client, query, topics, offset) {
const data = await client.query({
query,
variables: {
topics: topics.join(';'),
offset
}
});
return data
}
async fetchData() {
const { client, topics } = this.props;
const galleries = await this.fetchQuery(
client, galleryQuery, topics, galleryStart);
… // stuff that processes the galleries data
this.setState({
// update state with latest data});
}
query ($topics: String $offset: Int) {
Ceberus(
section: "most-popular"
rows: 4
start: $offset
type: "gallery"
topicLabel: $topics
) {
results
docs {
... on popularGallery {
title
type
topics {
label
}
imageLink
}
}
}
}
Query.gql graphql/index.js
export galleryQuery from './Query.gql';
component/index.js
async fetchQuery(client, query, topics, diff) {
const data = await client.query({
query,
variables: {
topics: topics.join(';'),
diff
}
});
return data
}
async fetchData() {
const { client, topics } = this.props;
const galleries = await this.fetchQuery(
client, galleryQuery, topics, galleryStart);
… // stuff that processes the galleries data
this.setState({
// update state with latest data});
}
Taming the beast - how to tame React & GraphQL, one error at a time
query ($topics: String $diff: Int) {
Ceberus(
section: "most-popular"
rows: 4
start: $diff
type: "gallery"
topicLabel: $topics
) {
results
docs {
... on popularGallery {
title
type
topics {
label
}
imageLink
}
}
}
}
Query.gql graphql/index.js
export galleryQuery from './Query.gql';
component/index.js
async fetchQuery(client, query, topics, diff) {
const data = await client.query({
query,
variables: {
topics: topics.join(';'),
diff
}
});
return data
}
async fetchData() {
const { client, topics } = this.props;
const galleries = await this.fetchQuery(
client, galleryQuery, topics, galleryStart);
… // stuff that processes the galleries data
this.setState({
// update state with latest data});
}
Solution	1:
Refactor	the	variable	name	across	the	
query	and	react	files
query ($topics: String $offset: Int) {
Ceberus(
section: "most-popular"
rows: 4
start: $offset
type: "gallery"
topicLabel: $topics
) {
results
docs {
... on popularGallery {
title
type
topics {
label
}
imageLink
}
}
}
}
Query.gql graphql/index.js
export galleryQuery from './Query.gql';
component/index.js
async fetchQuery(client, query, topics, diff) {
const data = await client.query({
query,
variables: {
topics: topics.join(';'),
offset: diff
}
});
return data
}
async fetchData() {
const { client, topics } = this.props;
const galleries = await this.fetchQuery(
client, galleryQuery, topics, galleryStart);
… // stuff that processes the galleries data
this.setState({
// update state with latest data});
}
Solution	2:
Expand	your	JSON	object
render() {
…
return (
<div className={styles.component}>
<div className={styles.overallContainer}>
{this.renderElements()}</div>
<Button onClick={this.handleLoadMore()} className={styles.moreButton}>
Show me more!
</Button>
</div>
);
}
handleLoadMore() {
this.fetchData();
}
async fetchData() {
const { client } = this.props;
const data = await this.fetchQuery(client, query);
const { elements } = this.processitems(data);
this.setState({
elements,
loading: false
});
}
Spot the error!
Hint: it still renders…
this.handleLoadMore()}
fetchData()
setState()
Render()
render() {
…
return (
<div className={styles.component}>
<div className={styles.overallContainer}>
{this.renderElements()}</div>
<Button onClick={() => this.handleLoadMore()} className={styles.moreButton}>
Show me more!
</Button>
</div>
);
}
handleLoadMore() {
this.fetchData();
}
async fetchData() {
const { client } = this.props;
const data = await this.fetchQuery(client, query);
const { elements } = this.processitems(data);
this.setState({
elements,
loading: false
});
}
Solution 1:
Arrow Funtction in
render
render() {
…
return (
<div className={styles.component}>
<div className={styles.overallContainer}>
{this.renderElements()}</div>
<Button onClick={this.handleLoadMore} className={styles.moreButton}>
Show me more!
</Button>
</div>
);
}
handleLoadMore() {
this.fetchData();
}
Solution 2:
Bind in Constructor!
constructor(props) {
super(props);
this.state = {
elements: [],
};
this.handleLoadMore = this.handleLoadMore.bind(this);
}
render() {
…
return (
<div className={styles.component}>
<div className={styles.overallContainer}>
{this.renderElements()}</div>
<Button onClick={this.handleLoadMore} className={styles.moreButton}>
Show me more!
</Button>
</div>
);
}
handleLoadMore = () => this.fetchData(); Solution 3:
Class properties
(note: React does not recommend this
though…)
constructor(props) {
super(props);
this.state = {
elements: [],
};
this.handleLoadMore = this.handleLoadMore.bind(this);
}
Binding	in	constructor	is	no	more	needed!
Spot the error!
Hint: You might want to debug with an IDE
debugger…..
componentWillReceiveProps({ attr }) {
const isPathChanged = attr.pathname !== this.props.location.pathname;
const isQueryChanged = attr.search !== this.props.location.search;
if (this.isMenuVisible && (isPathChanged || isQueryChanged)) {
this.toggleMenu();
}
this.processQueryString(attr.search);
}
setBody(qs) {
const setScroll = qs.has('menu') || qs.has('gallery');
if (setScroll) {
if (this.scrollTop === null) {
this.scrollTop = window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop;
}
} else if (this.scrollTop !== null) {
this.restoreScrollPosition(this.scrollTop);
this.scrollTop = null;
}
}
processQueryString(search) {
const qs = new URLSearchParams(search);
this.setBody(qs);
}
render() {
<Header toggleMenu={this.toggleMenu}. menuVisible={this.isMenuVisible}/>
}
toggleMenu() {
if (this.isMenuVisible) {
this.setState({ menuVisible: false });} else {this.setState({ menuVisible: true});
}
}
Answers on my
twitter:
@studioswong
Ad

More Related Content

What's hot (20)

Mastering RecyclerView Layouts
Mastering RecyclerView LayoutsMastering RecyclerView Layouts
Mastering RecyclerView Layouts
Dave Smith
 
20141001 delapsley-oc-openstack-final
20141001 delapsley-oc-openstack-final20141001 delapsley-oc-openstack-final
20141001 delapsley-oc-openstack-final
David Lapsley
 
Client-side Rendering with AngularJS
Client-side Rendering with AngularJSClient-side Rendering with AngularJS
Client-side Rendering with AngularJS
David Lapsley
 
An introduction to property-based testing
An introduction to property-based testingAn introduction to property-based testing
An introduction to property-based testing
Vincent Pradeilles
 
MVest Spring Job Execution
MVest Spring Job ExecutionMVest Spring Job Execution
MVest Spring Job Execution
Shraddha Bora
 
ERGroupware
ERGroupwareERGroupware
ERGroupware
WO Community
 
16 18
16 1816 18
16 18
Erick Regalado
 
Backbone.js Simple Tutorial
Backbone.js Simple TutorialBackbone.js Simple Tutorial
Backbone.js Simple Tutorial
추근 문
 
Android crashcourse
Android crashcourseAndroid crashcourse
Android crashcourse
Alexey Buzdin
 
tangowithdjango - Ch15
tangowithdjango - Ch15tangowithdjango - Ch15
tangowithdjango - Ch15
Asika Kuo
 
A (very) opinionated guide to MSBuild and Project Files
A (very) opinionated guide to MSBuild and Project FilesA (very) opinionated guide to MSBuild and Project Files
A (very) opinionated guide to MSBuild and Project Files
David Wengier
 
ReactでGraphQLを使っている
ReactでGraphQLを使っているReactでGraphQLを使っている
ReactでGraphQLを使っている
Takahiro Kobaru
 
Drupal 8: Fields reborn
Drupal 8: Fields rebornDrupal 8: Fields reborn
Drupal 8: Fields reborn
Pablo López Escobés
 
Recyclerview in action
Recyclerview in action Recyclerview in action
Recyclerview in action
Pratama Nur Wijaya
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF
Luc Bors
 
Node js mongodriver
Node js mongodriverNode js mongodriver
Node js mongodriver
christkv
 
JavaScript client API for Google Apps Script API primer
JavaScript client API for Google Apps Script API primerJavaScript client API for Google Apps Script API primer
JavaScript client API for Google Apps Script API primer
Bruce McPherson
 
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
David Wengier
 
A evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no androidA evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no android
Rodrigo de Souza Castro
 
JQuery New Evolution
JQuery New EvolutionJQuery New Evolution
JQuery New Evolution
Allan Huang
 
Mastering RecyclerView Layouts
Mastering RecyclerView LayoutsMastering RecyclerView Layouts
Mastering RecyclerView Layouts
Dave Smith
 
20141001 delapsley-oc-openstack-final
20141001 delapsley-oc-openstack-final20141001 delapsley-oc-openstack-final
20141001 delapsley-oc-openstack-final
David Lapsley
 
Client-side Rendering with AngularJS
Client-side Rendering with AngularJSClient-side Rendering with AngularJS
Client-side Rendering with AngularJS
David Lapsley
 
An introduction to property-based testing
An introduction to property-based testingAn introduction to property-based testing
An introduction to property-based testing
Vincent Pradeilles
 
MVest Spring Job Execution
MVest Spring Job ExecutionMVest Spring Job Execution
MVest Spring Job Execution
Shraddha Bora
 
Backbone.js Simple Tutorial
Backbone.js Simple TutorialBackbone.js Simple Tutorial
Backbone.js Simple Tutorial
추근 문
 
tangowithdjango - Ch15
tangowithdjango - Ch15tangowithdjango - Ch15
tangowithdjango - Ch15
Asika Kuo
 
A (very) opinionated guide to MSBuild and Project Files
A (very) opinionated guide to MSBuild and Project FilesA (very) opinionated guide to MSBuild and Project Files
A (very) opinionated guide to MSBuild and Project Files
David Wengier
 
ReactでGraphQLを使っている
ReactでGraphQLを使っているReactでGraphQLを使っている
ReactでGraphQLを使っている
Takahiro Kobaru
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF
Luc Bors
 
Node js mongodriver
Node js mongodriverNode js mongodriver
Node js mongodriver
christkv
 
JavaScript client API for Google Apps Script API primer
JavaScript client API for Google Apps Script API primerJavaScript client API for Google Apps Script API primer
JavaScript client API for Google Apps Script API primer
Bruce McPherson
 
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
David Wengier
 
A evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no androidA evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no android
Rodrigo de Souza Castro
 
JQuery New Evolution
JQuery New EvolutionJQuery New Evolution
JQuery New Evolution
Allan Huang
 

Similar to Taming the beast - how to tame React & GraphQL, one error at a time (20)

Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
Nick Lee
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Thomas Fuchs
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
Howard Lewis Ship
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
Rafael Felix da Silva
 
JavaScript JQUERY AJAX
JavaScript JQUERY AJAXJavaScript JQUERY AJAX
JavaScript JQUERY AJAX
Makarand Bhatambarekar
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
Jarod Ferguson
 
React table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilterReact table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilter
Katy Slemon
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
ES6 Primer
ES6 PrimerES6 Primer
ES6 Primer
roblund
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, Macoscope
Macoscope
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
Andrew Dupont
 
BOF2644 Developing Java EE 7 Scala apps
BOF2644 Developing Java EE 7 Scala appsBOF2644 Developing Java EE 7 Scala apps
BOF2644 Developing Java EE 7 Scala apps
Peter Pilgrim
 
HirshHorn theme: how I created it
HirshHorn theme: how I created itHirshHorn theme: how I created it
HirshHorn theme: how I created it
Paul Bearne
 
Experience Manager 6 Developer Features - Highlights
Experience Manager 6 Developer Features - HighlightsExperience Manager 6 Developer Features - Highlights
Experience Manager 6 Developer Features - Highlights
Cédric Hüsler
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Tsuyoshi Yamamoto
 
Data visualization in python/Django
Data visualization in python/DjangoData visualization in python/Django
Data visualization in python/Django
kenluck2001
 
droidparts
droidpartsdroidparts
droidparts
Droidcon Berlin
 
Iniciando com jquery
Iniciando com jqueryIniciando com jquery
Iniciando com jquery
Danilo Sousa
 
First java-server-faces-tutorial-en
First java-server-faces-tutorial-enFirst java-server-faces-tutorial-en
First java-server-faces-tutorial-en
techbed
 
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Alessandro Nadalin
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
Nick Lee
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Thomas Fuchs
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
Howard Lewis Ship
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
Rafael Felix da Silva
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
Jarod Ferguson
 
React table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilterReact table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilter
Katy Slemon
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
ES6 Primer
ES6 PrimerES6 Primer
ES6 Primer
roblund
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, Macoscope
Macoscope
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
Andrew Dupont
 
BOF2644 Developing Java EE 7 Scala apps
BOF2644 Developing Java EE 7 Scala appsBOF2644 Developing Java EE 7 Scala apps
BOF2644 Developing Java EE 7 Scala apps
Peter Pilgrim
 
HirshHorn theme: how I created it
HirshHorn theme: how I created itHirshHorn theme: how I created it
HirshHorn theme: how I created it
Paul Bearne
 
Experience Manager 6 Developer Features - Highlights
Experience Manager 6 Developer Features - HighlightsExperience Manager 6 Developer Features - Highlights
Experience Manager 6 Developer Features - Highlights
Cédric Hüsler
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Tsuyoshi Yamamoto
 
Data visualization in python/Django
Data visualization in python/DjangoData visualization in python/Django
Data visualization in python/Django
kenluck2001
 
Iniciando com jquery
Iniciando com jqueryIniciando com jquery
Iniciando com jquery
Danilo Sousa
 
First java-server-faces-tutorial-en
First java-server-faces-tutorial-enFirst java-server-faces-tutorial-en
First java-server-faces-tutorial-en
techbed
 
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Alessandro Nadalin
 
Ad

Recently uploaded (20)

Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software DevelopmentSecure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Shubham Joshi
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Douwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License codeDouwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License code
aneelaramzan63
 
Top 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docxTop 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docx
Portli
 
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
Andre Hora
 
Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025
kashifyounis067
 
Landscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature ReviewLandscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature Review
Hironori Washizaki
 
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
Egor Kaleynik
 
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Ranjan Baisak
 
Kubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptxKubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptx
CloudScouts
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025
kashifyounis067
 
Adobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest VersionAdobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest Version
kashifyounis067
 
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Orangescrum
 
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
AxisTechnolabs
 
Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)
Allon Mureinik
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025
mu394968
 
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software DevelopmentSecure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Shubham Joshi
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Douwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License codeDouwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License code
aneelaramzan63
 
Top 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docxTop 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docx
Portli
 
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
Andre Hora
 
Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025
kashifyounis067
 
Landscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature ReviewLandscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature Review
Hironori Washizaki
 
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
Egor Kaleynik
 
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Ranjan Baisak
 
Kubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptxKubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptx
CloudScouts
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025
kashifyounis067
 
Adobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest VersionAdobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest Version
kashifyounis067
 
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Orangescrum
 
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
AxisTechnolabs
 
Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)
Allon Mureinik
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025
mu394968
 
Ad

Taming the beast - how to tame React & GraphQL, one error at a time

  • 1. Taming The Beast How to tame React & GraphQL ^(One error at a time) Susanna Wong @studioswong
  • 2. Meet Cerberus. Cerberus kept perpetual watch at the gates, preventing the living from entering and the dead from leaving.
  • 4. |
  • 6. Step 1: Setting up the Query query ($topics: String $offset: Int) { Ceberus( section: "most-popular" rows: 4 start: $offset type: "gallery" topicLabel: $topics ) { results docs { ... on popularGallery { title type topics { label } imageLink } } } } Query.gql
  • 7. Step 2: Exporting the query and importing into React Component graphql/index.js component/index.js export galleryQuery from './Query.gql'; import { galleryQuery } from './graphql';
  • 8. Step 3: Construct functions for fetching Query within component component/index.js async fetchQuery(client, query, topics, offset) { const data = await client.query({ query, variables: { topics: topics.join(';'), offset } }); return data } async fetchData() { const { client, topics } = this.props; const galleries = await this.fetchQuery( client, galleryQuery, topics, galleryStart); … // stuff that processes the galleries data this.setState({ // update state with latest data}); }
  • 9. query ($topics: String $offset: Int) { Ceberus( section: "most-popular" rows: 4 start: $offset type: "gallery" topicLabel: $topics ) { results docs { ... on popularGallery { title type topics { label } imageLink } } } } Query.gql graphql/index.js export galleryQuery from './Query.gql'; component/index.js async fetchQuery(client, query, topics, offset) { const data = await client.query({ query, variables: { topics: topics.join(';'), offset } }); return data } async fetchData() { const { client, topics } = this.props; const galleries = await this.fetchQuery( client, galleryQuery, topics, galleryStart); … // stuff that processes the galleries data this.setState({ // update state with latest data}); }
  • 10. query ($topics: String $offset: Int) { Ceberus( section: "most-popular" rows: 4 start: $offset type: "gallery" topicLabel: $topics ) { results docs { ... on popularGallery { title type topics { label } imageLink } } } } Query.gql graphql/index.js export galleryQuery from './Query.gql'; component/index.js async fetchQuery(client, query, topics, diff) { const data = await client.query({ query, variables: { topics: topics.join(';'), diff } }); return data } async fetchData() { const { client, topics } = this.props; const galleries = await this.fetchQuery( client, galleryQuery, topics, galleryStart); … // stuff that processes the galleries data this.setState({ // update state with latest data}); }
  • 12. query ($topics: String $diff: Int) { Ceberus( section: "most-popular" rows: 4 start: $diff type: "gallery" topicLabel: $topics ) { results docs { ... on popularGallery { title type topics { label } imageLink } } } } Query.gql graphql/index.js export galleryQuery from './Query.gql'; component/index.js async fetchQuery(client, query, topics, diff) { const data = await client.query({ query, variables: { topics: topics.join(';'), diff } }); return data } async fetchData() { const { client, topics } = this.props; const galleries = await this.fetchQuery( client, galleryQuery, topics, galleryStart); … // stuff that processes the galleries data this.setState({ // update state with latest data}); } Solution 1: Refactor the variable name across the query and react files
  • 13. query ($topics: String $offset: Int) { Ceberus( section: "most-popular" rows: 4 start: $offset type: "gallery" topicLabel: $topics ) { results docs { ... on popularGallery { title type topics { label } imageLink } } } } Query.gql graphql/index.js export galleryQuery from './Query.gql'; component/index.js async fetchQuery(client, query, topics, diff) { const data = await client.query({ query, variables: { topics: topics.join(';'), offset: diff } }); return data } async fetchData() { const { client, topics } = this.props; const galleries = await this.fetchQuery( client, galleryQuery, topics, galleryStart); … // stuff that processes the galleries data this.setState({ // update state with latest data}); } Solution 2: Expand your JSON object
  • 14. render() { … return ( <div className={styles.component}> <div className={styles.overallContainer}> {this.renderElements()}</div> <Button onClick={this.handleLoadMore()} className={styles.moreButton}> Show me more! </Button> </div> ); } handleLoadMore() { this.fetchData(); } async fetchData() { const { client } = this.props; const data = await this.fetchQuery(client, query); const { elements } = this.processitems(data); this.setState({ elements, loading: false }); } Spot the error! Hint: it still renders…
  • 16. render() { … return ( <div className={styles.component}> <div className={styles.overallContainer}> {this.renderElements()}</div> <Button onClick={() => this.handleLoadMore()} className={styles.moreButton}> Show me more! </Button> </div> ); } handleLoadMore() { this.fetchData(); } async fetchData() { const { client } = this.props; const data = await this.fetchQuery(client, query); const { elements } = this.processitems(data); this.setState({ elements, loading: false }); } Solution 1: Arrow Funtction in render
  • 17. render() { … return ( <div className={styles.component}> <div className={styles.overallContainer}> {this.renderElements()}</div> <Button onClick={this.handleLoadMore} className={styles.moreButton}> Show me more! </Button> </div> ); } handleLoadMore() { this.fetchData(); } Solution 2: Bind in Constructor! constructor(props) { super(props); this.state = { elements: [], }; this.handleLoadMore = this.handleLoadMore.bind(this); }
  • 18. render() { … return ( <div className={styles.component}> <div className={styles.overallContainer}> {this.renderElements()}</div> <Button onClick={this.handleLoadMore} className={styles.moreButton}> Show me more! </Button> </div> ); } handleLoadMore = () => this.fetchData(); Solution 3: Class properties (note: React does not recommend this though…) constructor(props) { super(props); this.state = { elements: [], }; this.handleLoadMore = this.handleLoadMore.bind(this); } Binding in constructor is no more needed!
  • 19. Spot the error! Hint: You might want to debug with an IDE debugger….. componentWillReceiveProps({ attr }) { const isPathChanged = attr.pathname !== this.props.location.pathname; const isQueryChanged = attr.search !== this.props.location.search; if (this.isMenuVisible && (isPathChanged || isQueryChanged)) { this.toggleMenu(); } this.processQueryString(attr.search); } setBody(qs) { const setScroll = qs.has('menu') || qs.has('gallery'); if (setScroll) { if (this.scrollTop === null) { this.scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; } } else if (this.scrollTop !== null) { this.restoreScrollPosition(this.scrollTop); this.scrollTop = null; } } processQueryString(search) { const qs = new URLSearchParams(search); this.setBody(qs); } render() { <Header toggleMenu={this.toggleMenu}. menuVisible={this.isMenuVisible}/> } toggleMenu() { if (this.isMenuVisible) { this.setState({ menuVisible: false });} else {this.setState({ menuVisible: true}); } } Answers on my twitter: @studioswong