Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
React Suspense on Apollo
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Kodai Nakamura
August 02, 2018
Programming
1.6k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
React Suspense on Apollo
Kodai Nakamura
August 02, 2018
More Decks by Kodai Nakamura
See All by Kodai Nakamura
React Fire
kdnk
2
1.5k
wejs24.pdf
kdnk
1
1.2k
Local State Management with Apollo
kdnk
2
1.6k
Other Decks in Programming
See All in Programming
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
790
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
560
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.3k
これからAgentCoreを触る方へトレンドはGatewayです
har1101
2
310
Datadog LLM Observabilityで実現する 安全なLLM Usage 管理
3150
0
120
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
220
Oxcを導入して開発体験が向上した話
yug1224
4
340
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
610
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
180
Vite+ Unified Toolchain for the Web
naokihaba
0
360
A2UI という光を覗いてみる
satohjohn
1
160
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1k
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
85
9.5k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
240
First, design no harm
axbom
PRO
2
1.2k
Unsuck your backbone
ammeep
672
58k
How to build a perfect <img>
jonoalderson
1
5.7k
Writing Fast Ruby
sferik
630
63k
Become a Pro
speakerdeck
PRO
31
6k
Practical Orchestrator
shlominoach
191
11k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
380
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
Transcript
©2018 Wantedly, Inc. React Suspense on Apollo Meguro.es #16 @
LIVESENSE 2nd.August.2018 - Kodai Nakamura
©2018 Wantedly, Inc. React Suspense on Apollo Meguro.es #16 @
LIVESENSE 2nd.August.2018 - Kodai Nakamura
©2018 Wantedly, Inc. ࣗݾհ ,PEBJ/BLBNVSB (JUIVC!LEOL 5XJUUFS!LEOL@@ 4PGUXBSF&OHJOFFSBU8BOUFEMZ *OD৽ଔ +BWB4DSJQU
5ZQF4DSJQU 3FBDU 3BJMT 3VCZ
©2018 Wantedly, Inc. "QPMMPͰ3FBDU4VTQFOTF͕͑Δʁ Page Title Page Subtitle
©2018 Wantedly, Inc. ࠓ"QPMMPͰ ඇಉظϨϯμϦϯά͕Ͱ͖Δ "TZOD.PEFͷհͰ͢ Page Title Page Subtitle
©2018 Wantedly, Inc. ࣍ ‣3FBDU4VTQFOTF ‣"QPMMP$MJFOUͰ3FBDU4VTQFOTF
©2018 Wantedly, Inc. 3FBDUl4VTQFOTFz Page Title Page Subtitle
©2018 Wantedly, Inc. React Suspense 3FBDUl4VTQFOTFz ‣ ࠓͷ+4$POG*DFMBOEͰൃද͞Εͨ ‣ ͓ͦΒ͘SFBDUͰ͑Δ
‣ ඇಉظΛ͍͍ײ͡ʹѻ͑Δͷ ‣ SFOEFS ͷதͰUISPXOFX1SPNJTF͢Δ
©2018 Wantedly, Inc. React Suspense ͳΜͰඞཁʁ ‣ 69ͷ্ ‣ OFUXPSLڥͷҧ͍ʹରԠ͢Δ
4QJOOFS͕Ұॠ͚ͩදࣔ͞ΕΔ ը૾͕ͳঢ়ଶͰSFOEFS͞ΕΔ ‣ ࠓͩͱɺMPBEJOH͔Ͳ͏͔ͷνΣοΫΛ͢Δ
©2018 Wantedly, Inc. React Suspense தͲ͏ͳͬͯΔʁ ‣ SFOEFSϝιουͷதͰDBDIF͔ΒΛऔಘ͢Δ ‣ DBDIF͕͋Δͱ͖ɺී௨ʹSFOEFS
‣ DBDIF͕ͳ͍ͱ͖ɺUISPXOFX1SPNJTF͢Δ 1SPNJTF͕SFTPMWF͞Ε͍ͯͳ͍߹SFOEFS͠ͳ͍ 1SPNJTF͕SFTPMWF͞ΕͨΒ࠶SFOEFS
©2018 Wantedly, Inc. React Suspense தͲ͏ͳͬͯΔʁ ‣ SFOEFSϝιουͷதͰDBDIF͔ΒΛऔಘ͢Δ ‣ DBDIF͕͋Δͱ͖ɺී௨ʹSFOEFS
‣ DBDIF͕ͳ͍ͱ͖ɺUISPXOFX1SPNJTF͢Δ 1SPNJTF͕SFTPMWF͞Ε͍ͯͳ͍߹SFOEFS͠ͳ͍ 1SPNJTF͕SFTPMWF͞ΕͨΒ࠶SFOEFS 1SPNJTFΛUISPX
©2018 Wantedly, Inc. React Suspense &SSPS#PVOEBSJFT class ErrorBoundary extends React.Component
{ constructor(props) { super(props); this.state = { hasError: false }; } componentDidCatch(error, info) { this.setState({ hasError: true }); logErrorToMyService(error, info); } render() { if (this.state.hasError) { return <h1>Something went wrong.</h1>; } return this.props.children; } } <ErrorBoundary> <MyWidget /> </ErrorBoundary> ‣ ࢠίϯϙʔωϯτͷΤϥʔΛίϯϙʔωϯτͰ DBUDI͢ΔΈ ‣ +4ͷDBUDIΈ͍ͨͳ͜ͱ͕$PNQPOFOUͰ Ͱ͖ΔΑ͏ʹͳΔ ‣ એݴతʹ͔͚Δ ‣ DPNQPOFOU%JE$BUDIͰัଊͰ͖Δ
©2018 Wantedly, Inc. React Suspense &SSPS#PVOEBSJFT class ErrorBoundary extends React.Component
{ constructor(props) { super(props); this.state = { hasError: false }; } componentDidCatch(error, info) { this.setState({ hasError: true }); logErrorToMyService(error, info); } render() { if (this.state.hasError) { return <h1>Something went wrong.</h1>; } return this.props.children; } } <ErrorBoundary> <MyWidget /> </ErrorBoundary> ‣ ࢠίϯϙʔωϯτͷΤϥʔΛίϯϙʔωϯτͰ DBUDI͢ΔΈ ‣ +4ͷDBUDIΈ͍ͨͳ͜ͱ͕$PNQPOFOUͰ Ͱ͖ΔΑ͏ʹͳΔ ‣ એݴతʹ͔͚Δ ‣ DPNQPOFOU%JE$BUDIͰัଊͰ͖Δ
©2018 Wantedly, Inc. React Suspense &SSPS#PVOEBSJFT class ErrorBoundary extends React.Component
{ constructor(props) { super(props); this.state = { hasError: false }; } componentDidCatch(error, info) { this.setState({ hasError: true }); logErrorToMyService(error, info); } render() { if (this.state.hasError) { return <h1>Something went wrong.</h1>; } return this.props.children; } } <ErrorBoundary> <MyWidget /> </ErrorBoundary> ‣ ࢠίϯϙʔωϯτͷΤϥʔΛίϯϙʔωϯτͰ DBUDI͢ΔΈ ‣ +4ͷDBUDIΈ͍ͨͳ͜ͱ͕$PNQPOFOUͰ Ͱ͖ΔΑ͏ʹͳΔ ‣ એݴతʹ͔͚Δ ‣ DPNQPOFOU%JE$BUDIͰัଊͰ͖Δ
©2018 Wantedly, Inc. React Suspense &SSPS#PVOEBSJFT class ErrorBoundary extends React.Component
{ constructor(props) { super(props); this.state = { hasError: false }; } componentDidCatch(error, info) { this.setState({ hasError: true }); logErrorToMyService(error, info); } render() { if (this.state.hasError) { return <h1>Something went wrong.</h1>; } return this.props.children; } } <ErrorBoundary> <MyWidget /> </ErrorBoundary> ‣ ࢠίϯϙʔωϯτͷΤϥʔΛίϯϙʔωϯτͰ DBUDI͢ΔΈ ‣ +4ͷDBUDIΈ͍ͨͳ͜ͱ͕$PNQPOFOUͰ Ͱ͖ΔΑ͏ʹͳΔ ‣ એݴతʹ͔͚Δ ‣ DPNQPOFOU%JE$BUDIͰัଊͰ͖Δ
©2018 Wantedly, Inc. React Suspense TJNQMFDBDIFQSPWJEFS ‣ DBDIFΛ͍ͯ͠Δͱ͜Ζͷ࣮ ‣ GBDFCPPLSFBDUʹೖ͍ͬͯΔ
‣ ໊લͱ͔࣮ͱ͔มΘΔ͔ import {createResource} from 'simple-cache-provider'; async function searchMovies(query) { const response = await fetch(/* URL */); return await response.json(); } const readMovieSearchResults = createResource(searchMovies); function Results(/* args */) { // ... const {results} = readMovieSearchResults(cache, query); return ( <div> {results.slice(0, 5).map(result => { return ( <Result result={result} // ... /> ); })} </div> ); }
©2018 Wantedly, Inc. React Suspense TJNQMFDBDIFQSPWJEFS ‣ DBDIFΛ͍ͯ͠Δͱ͜Ζͷ࣮ ‣ GBDFCPPLSFBDUʹೖ͍ͬͯΔ
‣ ໊લͱ͔࣮ͱ͔มΘΔ͔ import {createResource} from 'simple-cache-provider'; async function searchMovies(query) { const response = await fetch(/* URL */); return await response.json(); } const readMovieSearchResults = createResource(searchMovies); function Results(/* args */) { // ... const {results} = readMovieSearchResults(cache, query); return ( <div> {results.slice(0, 5).map(result => { return ( <Result result={result} // ... /> ); })} </div> ); }
©2018 Wantedly, Inc. React Suspense TJNQMFDBDIFQSPWJEFS ‣ DBDIFΛ͍ͯ͠Δͱ͜Ζͷ࣮ ‣ GBDFCPPLSFBDUʹೖ͍ͬͯΔ
‣ ໊લͱ͔࣮ͱ͔มΘΔ͔ import {createResource} from 'simple-cache-provider'; async function searchMovies(query) { const response = await fetch(/* URL */); return await response.json(); } const readMovieSearchResults = createResource(searchMovies); function Results(/* args */) { // ... const {results} = readMovieSearchResults(cache, query); return ( <div> {results.slice(0, 5).map(result => { return ( <Result result={result} // ... /> ); })} </div> ); }
©2018 Wantedly, Inc. React Suspense TJNQMFDBDIFQSPWJEFS ‣ DBDIFΛ͍ͯ͠Δͱ͜Ζͷ࣮ ‣ GBDFCPPLSFBDUʹೖ͍ͬͯΔ
‣ ໊લͱ͔࣮ͱ͔มΘΔ͔ import {createResource} from 'simple-cache-provider'; async function searchMovies(query) { const response = await fetch(/* URL */); return await response.json(); } const readMovieSearchResults = createResource(searchMovies); function Results(/* args */) { // ... const {results} = readMovieSearchResults(cache, query); return ( <div> {results.slice(0, 5).map(result => { return ( <Result result={result} // ... /> ); })} </div> ); }
©2018 Wantedly, Inc. React Suspense TJNQMFDBDIFQSPWJEFS ‣ DBDIFΛ͍ͯ͠Δͱ͜Ζͷ࣮ ‣ GBDFCPPLSFBDUʹೖ͍ͬͯΔ
‣ ໊લͱ͔࣮ͱ͔มΘΔ͔ import {createResource} from 'simple-cache-provider'; async function searchMovies(query) { const response = await fetch(/* URL */); return await response.json(); } const readMovieSearchResults = createResource(searchMovies); function Results(/* args */) { // ... const {results} = readMovieSearchResults(cache, query); return ( <div> {results.slice(0, 5).map(result => { return ( <Result result={result} // ... /> ); })} </div> ); } ͜͜ͰDBDIF͔Βऔͬͯ͘Δ
©2018 Wantedly, Inc. React Suspense TJNQMFDBDIFQSPWJEFS ‣ DBDIFΛ͍ͯ͠Δͱ͜Ζͷ࣮ ‣ GBDFCPPLSFBDUʹೖ͍ͬͯΔ
‣ ໊લͱ͔࣮ͱ͔มΘΔ͔ import {createResource} from 'simple-cache-provider'; async function searchMovies(query) { const response = await fetch(/* URL */); return await response.json(); } const readMovieSearchResults = createResource(searchMovies); function Results(/* args */) { // ... const {results} = readMovieSearchResults(cache, query); return ( <div> {results.slice(0, 5).map(result => { return ( <Result result={result} // ... /> ); })} </div> ); } DBDIF͕ͳ͔ͬͨΒUISPXOFX1SPNJTF
©2018 Wantedly, Inc. React Suspense TJNQMFDBDIFQSPWJEFS ‣ DBDIFΛ͍ͯ͠Δͱ͜Ζͷ࣮ ‣ GBDFCPPLSFBDUʹೖ͍ͬͯΔ
‣ ໊લͱ͔࣮ͱ͔มΘΔ͔ let cachedResults = null; const readMovieSearchResults = ({query}) => { if (cachedResults) { return cachedResults; } throw new Promise(async resolve => { const results = await searchMovies(query); cachedResults = results; resolve(); }); }; TJNQMFDBDIFQSPWJEFS͕ͳ͔ͬͨΒ͜Μͳײ͡ʹͳΔͣ
©2018 Wantedly, Inc. React Suspense TJNQMFDBDIFQSPWJEFS ‣ DBDIFΛ͍ͯ͠Δͱ͜Ζͷ࣮ ‣ GBDFCPPLSFBDUʹೖ͍ͬͯΔ
‣ ໊લͱ͔࣮ͱ͔มΘΔ͔ let cachedResults = null; const readMovieSearchResults = ({query}) => { if (cachedResults) { return cachedResults; } throw new Promise(async resolve => { const results = await searchMovies(query); cachedResults = results; resolve(); }); }; TJNQMFDBDIFQSPWJEFS͕ͳ͔ͬͨΒ͜Μͳײ͡ʹͳΔͣ
©2018 Wantedly, Inc. React Suspense TJNQMFDBDIFQSPWJEFS ‣ DBDIFΛ͍ͯ͠Δͱ͜Ζͷ࣮ ‣ GBDFCPPLSFBDUʹೖ͍ͬͯΔ
‣ ໊લͱ͔࣮ͱ͔มΘΔ͔ let cachedResults = null; const readMovieSearchResults = ({query}) => { if (cachedResults) { return cachedResults; } throw new Promise(async resolve => { const results = await searchMovies(query); cachedResults = results; resolve(); }); }; TJNQMFDBDIFQSPWJEFS͕ͳ͔ͬͨΒ͜Μͳײ͡ʹͳΔͣ
©2018 Wantedly, Inc. React Suspense 3FBDU5JNFPVU ‣ ·ͣEJE5JNFPVUGBMTFͰݺͼग़͞ΕΔ ‣ DIJMESFO͕SFOEFS͞ΕΔͱDBDIFݟʹߦ͘
‣ ଘࡏ͠ͳ͍ͱ͖ɺ1SPNJTF͕UISPX͞ΕΔ ‣ UISPXΛDBUDIͨ͠Βɺ͏Ұ࣮ߦ ‣ EJE5JNFPVUUSVFͱͳͬͯɺGBMMCBDL͕දࣔ͞ΕΔ ‣ 1SPNJTF͕SFTPMWF͢ΔͱEJE5JNFPVUGBMTF DIJMESFO͕SFOEFS͞ΕΔ import React, {Fragment} from 'react'; function Timeout({ms, fallback, children}) { return ( <React.Timeout ms={ms}> {didTimeout => ( <Fragment> <span hidden={didTimeout}>{children}</span> {didTimeout ? fallback : null} </Fragment> )} </React.Timeout> ); } export default Timeout;
©2018 Wantedly, Inc. React Suspense 3FBDU5JNFPVU ‣ ·ͣEJE5JNFPVUGBMTFͰݺͼग़͞ΕΔ ‣ DIJMESFO͕SFOEFS͞ΕΔͱDBDIFݟʹߦ͘
‣ ଘࡏ͠ͳ͍ͱ͖ɺ1SPNJTF͕UISPX͞ΕΔ ‣ UISPXΛDBUDIͨ͠Βɺ͏Ұ࣮ߦ ‣ EJE5JNFPVUUSVFͱͳͬͯɺGBMMCBDL͕දࣔ͞ΕΔ ‣ 1SPNJTF͕SFTPMWF͢ΔͱEJE5JNFPVUGBMTF DIJMESFO͕SFOEFS͞ΕΔ import React, {Fragment} from 'react'; function Timeout({ms, fallback, children}) { return ( <React.Timeout ms={ms}> {didTimeout => ( <Fragment> <span hidden={didTimeout}>{children}</span> {didTimeout ? fallback : null} </Fragment> )} </React.Timeout> ); } export default Timeout;
©2018 Wantedly, Inc. React Suspense 3FBDU5JNFPVU ‣ ·ͣEJE5JNFPVUGBMTFͰݺͼग़͞ΕΔ ‣ DIJMESFO͕SFOEFS͞ΕΔͱDBDIFݟʹߦ͘
‣ ଘࡏ͠ͳ͍ͱ͖ɺ1SPNJTF͕UISPX͞ΕΔ ‣ UISPXΛDBUDIͨ͠Βɺ͏Ұ࣮ߦ ‣ EJE5JNFPVUUSVFͱͳͬͯɺGBMMCBDL͕දࣔ͞ΕΔ ‣ 1SPNJTF͕SFTPMWF͢ΔͱEJE5JNFPVUGBMTF DIJMESFO͕SFOEFS͞ΕΔ import React, {Fragment} from 'react'; function Timeout({ms, fallback, children}) { return ( <React.Timeout ms={ms}> {didTimeout => ( <Fragment> <span hidden={didTimeout}>{children}</span> {didTimeout ? fallback : null} </Fragment> )} </React.Timeout> ); } export default Timeout;
©2018 Wantedly, Inc. React Suspense 3FBDU5JNFPVU ‣ ·ͣEJE5JNFPVUGBMTFͰݺͼग़͞ΕΔ ‣ DIJMESFO͕SFOEFS͞ΕΔͱDBDIFݟʹߦ͘
‣ ଘࡏ͠ͳ͍ͱ͖ɺ1SPNJTF͕UISPX͞ΕΔ ‣ UISPXΛDBUDIͨ͠Βɺ͏Ұ࣮ߦ ‣ EJE5JNFPVUUSVFͱͳͬͯɺGBMMCBDL͕දࣔ͞ΕΔ ‣ 1SPNJTF͕SFTPMWF͢ΔͱEJE5JNFPVUGBMTF DIJMESFO͕SFOEFS͞ΕΔ import React, {Fragment} from 'react'; function Timeout({ms, fallback, children}) { return ( <React.Timeout ms={ms}> {didTimeout => ( <Fragment> <span hidden={didTimeout}>{children}</span> {didTimeout ? fallback : null} </Fragment> )} </React.Timeout> ); } export default Timeout;
©2018 Wantedly, Inc. React Suspense 3FBDU5JNFPVU ‣ ·ͣEJE5JNFPVUGBMTFͰݺͼग़͞ΕΔ ‣ DIJMESFO͕SFOEFS͞ΕΔͱDBDIFݟʹߦ͘
‣ ଘࡏ͠ͳ͍ͱ͖ɺ1SPNJTF͕UISPX͞ΕΔ ‣ UISPXΛDBUDIͨ͠Βɺ͏Ұ࣮ߦ ‣ EJE5JNFPVUUSVFͱͳͬͯɺGBMMCBDL͕දࣔ͞ΕΔ ‣ 1SPNJTF͕SFTPMWF͢ΔͱEJE5JNFPVUGBMTF DIJMESFO͕SFOEFS͞ΕΔ import React, {Fragment} from 'react'; function Timeout({ms, fallback, children}) { return ( <React.Timeout ms={ms}> {didTimeout => ( <Fragment> <span hidden={didTimeout}>{children}</span> {didTimeout ? fallback : null} </Fragment> )} </React.Timeout> ); } export default Timeout;
©2018 Wantedly, Inc. React Suspense 3FBDU5JNFPVU ‣ ·ͣEJE5JNFPVUGBMTFͰݺͼग़͞ΕΔ ‣ DIJMESFO͕SFOEFS͞ΕΔͱDBDIFݟʹߦ͘
‣ ଘࡏ͠ͳ͍ͱ͖ɺ1SPNJTF͕UISPX͞ΕΔ ‣ UISPXΛDBUDIͨ͠Βɺ͏Ұ࣮ߦ ‣ EJE5JNFPVUUSVFͱͳͬͯɺGBMMCBDL͕දࣔ͞ΕΔ ‣ 1SPNJTF͕SFTPMWF͢ΔͱEJE5JNFPVUGBMTF DIJMESFO͕SFOEFS͞ΕΔ import React, {Fragment} from 'react'; function Timeout({ms, fallback, children}) { return ( <React.Timeout ms={ms}> {didTimeout => ( <Fragment> <span hidden={didTimeout}>{children}</span> {didTimeout ? fallback : null} </Fragment> )} </React.Timeout> ); } export default Timeout;
©2018 Wantedly, Inc. React Suspense 3FBDU5JNFPVU ‣ ·ͣEJE5JNFPVUGBMTFͰݺͼग़͞ΕΔ ‣ DIJMESFO͕SFOEFS͞ΕΔͱDBDIFݟʹߦ͘
‣ ଘࡏ͠ͳ͍ͱ͖ɺ1SPNJTF͕UISPX͞ΕΔ ‣ UISPXΛDBUDIͨ͠Βɺ͏Ұ࣮ߦ ‣ EJE5JNFPVUUSVFͱͳͬͯɺGBMMCBDL͕දࣔ͞ΕΔ ‣ 1SPNJTF͕SFTPMWF͢ΔͱEJE5JNFPVUGBMTFɻ DIJMESFO͕SFOEFS͞ΕΔ import React, {Fragment} from 'react'; function Timeout({ms, fallback, children}) { return ( <React.Timeout ms={ms}> {didTimeout => ( <Fragment> <span hidden={didTimeout}>{children}</span> {didTimeout ? fallback : null} </Fragment> )} </React.Timeout> ); } export default Timeout;
©2018 Wantedly, Inc. ‣ ·ͣEJE5JNFPVUGBMTFͰݺͼग़͞ΕΔ ‣ DIJMESFO͕SFOEFS͞ΕΔͱDBDIFݟʹߦ͘ ‣ ଘࡏ͠ͳ͍ͱ͖ɺ1SPNJTF͕UISPX͞ΕΔ ‣
UISPXΛDBUDIͨ͠ΒɺNTͬͯ͏Ұ࣮ߦ ‣ EJE5JNFPVUUSVFͱͳͬͯɺGBMMCBDL͕දࣔ͞ΕΔ ‣ 1SPNJTF͕SFTPMWF͢ΔͱEJE5JNFPVUGBMTFɻ DIJMESFO͕SFOEFS͞ΕΔ React Suspense 3FBDU5JNFPVU import React, {Fragment} from 'react'; function Timeout({ms, fallback, children}) { return ( <React.Timeout ms={ms}> {didTimeout => ( <Fragment> <span hidden={didTimeout}>{children}</span> {didTimeout ? fallback : null} </Fragment> )} </React.Timeout> ); } export default Timeout;
©2018 Wantedly, Inc. "QPMMP$MJFOUͰͰ͖Δʁ Page Title Page Subtitle
©2018 Wantedly, Inc. React Suspense on Apollo "TZOD.PEF const Photo
= ({ breed }) => ( <Query suspend query={GET_DOG_PHOTO} variables={breed && { breed }}> {({ data }) => { return <Image src={data.dog.displayImage} />; }} </Query> ); ‣ ͳΜͯݺͿ͔Θ͔Βͳ͍ ‣ ࠷ॳQSPQTͷ໊લ͕"TZD.PEFͩͬͨ ‣ 3FBDU"QPMMPͰϦϦʔε͢ΔΒ͍͠ ‣ "QPMMP$MJFOUͷ2VFSZ .VUBUJPOίϯ ϙʔωϯτͰ؆୯ʹඇಉظϨϯμϦϯά͕ Ͱ͖Δ
©2018 Wantedly, Inc. React Suspense on Apollo const Photo =
({ breed }) => ( <Query suspend query={GET_DOG_PHOTO} variables={breed && { breed }}> {({ data }) => { return <Image src={data.dog.displayImage} />; }} </Query> ); ‣ ͳΜͯݺͿ͔Θ͔Βͳ͍ ‣ ࠷ॳQSPQTͷ໊લ͕"TZD.PEFͩͬͨ ‣ 3FBDU"QPMMPͰϦϦʔε͢ΔΒ͍͠ ‣ "QPMMP$MJFOUͷ2VFSZ .VUBUJPOίϯ ϙʔωϯτͰ؆୯ʹඇಉظϨϯμϦϯά͕ Ͱ͖Δ "TZOD.PEF
©2018 Wantedly, Inc. React Suspense on Apollo const Photo =
({ breed }) => ( <Query suspend query={GET_DOG_PHOTO} variables={breed && { breed }}> {({ data }) => { return <Image src={data.dog.displayImage} />; }} </Query> ); const Photo = ({ breed }) => ( <Query query={GET_DOG_PHOTO} variables={breed && { breed }}> {({ data, loading }) => { if (loading) return <Loading /> return <Image src={data.dog.displayImage} />; }} </Query> ); ‣ ͳΜͯݺͿ͔Θ͔Βͳ͍ ‣ ࠷ॳQSPQTͷ໊લ͕"TZD.PEFͩͬͨ ‣ 3FBDU"QPMMPͰϦϦʔε͢ΔΒ͍͠ ‣ "QPMMP$MJFOUͷ2VFSZ .VUBUJPOίϯ ϙʔωϯτͰ؆୯ʹඇಉظϨϯμϦϯά͕ Ͱ͖Δ "TZOD.PEF
©2018 Wantedly, Inc. React Suspense on Apollo const Photo =
({ breed }) => ( <Query suspend query={GET_DOG_PHOTO} variables={breed && { breed }}> {({ data }) => { return <Image src={data.dog.displayImage} />; }} </Query> ); const Photo = ({ breed }) => ( <Query query={GET_DOG_PHOTO} variables={breed && { breed }}> {({ data, loading }) => { if (loading) return <Loading /> return <Image src={data.dog.displayImage} />; }} </Query> ); ‣ ͳΜͯݺͿ͔Θ͔Βͳ͍ ‣ ࠷ॳQSPQTͷ໊લ͕"TZD.PEFͩͬͨ ‣ 3FBDU"QPMMPͰϦϦʔε͢ΔΒ͍͠ ‣ "QPMMP$MJFOUͷ2VFSZ .VUBUJPOίϯ ϙʔωϯτͰ؆୯ʹඇಉظϨϯμϦϯά͕ Ͱ͖Δ "TZOD.PEF
©2018 Wantedly, Inc. React Suspense on Apollo const Photo =
({ breed }) => ( <Query suspend query={GET_DOG_PHOTO} variables={breed && { breed }}> {({ data }) => { return <Image src={data.dog.displayImage} />; }} </Query> ); <Timeout ms={2000}> {expired => expired && selectedDog ? ( <Loading /> ) : ( <Photo breed={selectedDog} /> ) } </Timeout> ‣ ͳΜͯݺͿ͔Θ͔Βͳ͍ ‣ ࠷ॳQSPQTͷ໊લ͕"TZD.PEFͩͬͨ ‣ 3FBDU"QPMMPͰϦϦʔε͢ΔΒ͍͠ ‣ "QPMMP$MJFOUͷ2VFSZ .VUBUJPOίϯ ϙʔωϯτͰ؆୯ʹඇಉظϨϯμϦϯά͕ Ͱ͖Δ "TZOD.PEF
©2018 Wantedly, Inc. React Suspense on Apollo Ͳ͏࣮ͬͯ͞Ε͍ͯΔ͔ class Query
extends React.Component { // ... render() { return this.props.children(this.getQueryResult(this.state)); } //... } private getQueryResult = ({queryObservable, evictData}) => { const currentResult = queryObservable!.currentResult(); const { loading, networkStatus, errors } = currentResult; if (loading) { if (this.props.suspend) { throw this.state.queryObservable!.result(); } Object.assign(data.data, this.previousData, currentResult.data); } else if (error) { // ... }; ‣ SFOEFSͷதͰHFU2VFSZ3FTVMU͕ݺΕ͍ͯΔ ‣ ͦͷதͰMPEJOHTVTQFOEͩͬͨΒ 1SPNJTFΛUISPX
©2018 Wantedly, Inc. React Suspense on Apollo Ͳ͏࣮ͬͯ͞Ε͍ͯΔ͔ class Query
extends React.Component { // ... render() { return this.props.children(this.getQueryResult(this.state)); } //... } private getQueryResult = ({queryObservable, evictData}) => { const currentResult = queryObservable!.currentResult(); const { loading, networkStatus, errors } = currentResult; if (loading) { if (this.props.suspend) { throw this.state.queryObservable!.result(); } Object.assign(data.data, this.previousData, currentResult.data); } else if (error) { // ... }; ‣ SFOEFSͷதͰHFU2VFSZ3FTVMU͕ݺΕ͍ͯΔ ‣ ͦͷதͰMPEJOHTVTQFOEͩͬͨΒ 1SPNJTFΛUISPX
©2018 Wantedly, Inc. React Suspense on Apollo Ͳ͏࣮ͬͯ͞Ε͍ͯΔ͔ class Query
extends React.Component { // ... render() { return this.props.children(this.getQueryResult(this.state)); } //... } private getQueryResult = ({queryObservable, evictData}) => { const currentResult = queryObservable!.currentResult(); const { loading, networkStatus, errors } = currentResult; if (loading) { if (this.props.suspend) { throw this.state.queryObservable!.result(); } Object.assign(data.data, this.previousData, currentResult.data); } else if (error) { // ... }; ‣ SFOEFSͷதͰHFU2VFSZ3FTVMU͕ݺΕ͍ͯΔ ‣ ͦͷதͰMPEJOHTVTQFOEͩͬͨΒ 1SPNJTFΛUISPX
©2018 Wantedly, Inc. React Suspense on Apollo Ͳ͏࣮ͬͯ͞Ε͍ͯΔ͔ class Query
extends React.Component { // ... render() { return this.props.children(this.getQueryResult(this.state)); } //... } private getQueryResult = ({queryObservable, evictData}) => { const currentResult = queryObservable!.currentResult(); const { loading, networkStatus, errors } = currentResult; if (loading) { if (this.props.suspend) { throw this.state.queryObservable!.result(); } Object.assign(data.data, this.previousData, currentResult.data); } else if (error) { // ... }; ‣ SFOEFSͷதͰHFU2VFSZ3FTVMU͕ݺΕ͍ͯΔ ‣ ͦͷதͰMPEJOHTVTQFOEͩͬͨΒ 1SPNJTFΛUISPX
©2018 Wantedly, Inc. React Suspense on Apollo Ͳ͏࣮ͬͯ͞Ε͍ͯΔ͔ class Query
extends React.Component { // ... render() { return this.props.children(this.getQueryResult(this.state)); } //... } private getQueryResult = ({queryObservable, evictData}) => { const currentResult = queryObservable!.currentResult(); const { loading, networkStatus, errors } = currentResult; if (loading) { if (this.props.suspend) { throw this.state.queryObservable!.result(); } Object.assign(data.data, this.previousData, currentResult.data); } else if (error) { // ... }; ‣ SFOEFSͷதͰHFU2VFSZ3FTVMU͕ݺΕ͍ͯΔ ‣ ͦͷதͰMPEJOHTVTQFOEͩͬͨΒ 1SPNJTFΛUISPX
©2018 Wantedly, Inc. ·ͱΊ ‣4VQFOTF3FBDUͰ͑ΔΑ͏ʹͳΔ ‣"QPMMPͰͷ"TZOD3FOEFSJOH3FBDU"QPMMPͰ EFGFS4FU4UBUFΛͬͨ-PX1SJPSJUZͱ͔͑Δ ‣IUUQTDPEFTBOECPYJPT[LYWL͜͜Ͱ3FBDU4VTQFOTF৮ΕΔ ‣IUUQTDPEFTBOECPYJPTWKYM͜͜Ͱ"QPMMPͷ"TZODSFOEFSJOHΛ
৮ΕΔ