Slide 1

Slide 1 text

©2018 Wantedly, Inc. React Suspense on Apollo Meguro.es #16 @ LIVESENSE 2nd.August.2018 - Kodai Nakamura

Slide 2

Slide 2 text

©2018 Wantedly, Inc. React Suspense on Apollo Meguro.es #16 @ LIVESENSE 2nd.August.2018 - Kodai Nakamura

Slide 3

Slide 3 text

©2018 Wantedly, Inc. ࣗݾ঺հ ,PEBJ/BLBNVSB (JUIVC!LEOL 5XJUUFS!LEOL@@ 4PGUXBSF&OHJOFFSBU8BOUFEMZ *OD৽ଔ +BWB4DSJQU 5ZQF4DSJQU 3FBDU 3BJMT 3VCZ

Slide 4

Slide 4 text

©2018 Wantedly, Inc. "QPMMPͰ3FBDU4VTQFOTF͕࢖͑Δʁ Page Title Page Subtitle

Slide 5

Slide 5 text

©2018 Wantedly, Inc. ࠓ೔͸"QPMMPͰ ඇಉظϨϯμϦϯά͕Ͱ͖Δ "TZOD.PEFͷ঺հͰ͢ Page Title Page Subtitle

Slide 6

Slide 6 text

©2018 Wantedly, Inc. ໨࣍ ‣3FBDU4VTQFOTF ‣"QPMMP$MJFOUͰ3FBDU4VTQFOTF

Slide 7

Slide 7 text

©2018 Wantedly, Inc. 3FBDUl4VTQFOTFz  Page Title Page Subtitle

Slide 8

Slide 8 text

©2018 Wantedly, Inc. React Suspense 3FBDUl4VTQFOTFz ‣ ࠓ೥ͷ+4$POG*DFMBOEͰൃද͞Εͨ ‣ ͓ͦΒ͘SFBDUͰ͸࢖͑Δ ‣ ඇಉظΛ͍͍ײ͡ʹѻ͑Δ΋ͷ ‣ SFOEFS ͷதͰUISPXOFX1SPNJTF͢Δ

Slide 9

Slide 9 text

©2018 Wantedly, Inc. React Suspense ͳΜͰඞཁʁ ‣ 69ͷ޲্ ‣ OFUXPSL؀ڥͷҧ͍ʹରԠ͢Δ  4QJOOFS͕Ұॠ͚ͩදࣔ͞ΕΔ  ը૾͕൒୺ͳঢ়ଶͰSFOEFS͞ΕΔ ‣ ࠓͩͱɺMPBEJOH͔Ͳ͏͔ͷνΣοΫΛ͢Δ

Slide 10

Slide 10 text

©2018 Wantedly, Inc. React Suspense த਎͸Ͳ͏ͳͬͯΔʁ ‣ SFOEFSϝιουͷதͰ͸DBDIF͔Β஋Λऔಘ͢Δ ‣ DBDIF͕͋Δͱ͖͸ɺී௨ʹSFOEFS ‣ DBDIF͕ͳ͍ͱ͖͸ɺUISPXOFX1SPNJTF͢Δ  1SPNJTF͕SFTPMWF͞Ε͍ͯͳ͍৔߹͸SFOEFS͠ͳ͍  1SPNJTF͕SFTPMWF͞ΕͨΒ࠶SFOEFS

Slide 11

Slide 11 text

©2018 Wantedly, Inc. React Suspense த਎͸Ͳ͏ͳͬͯΔʁ ‣ SFOEFSϝιουͷதͰ͸DBDIF͔Β஋Λऔಘ͢Δ ‣ DBDIF͕͋Δͱ͖͸ɺී௨ʹSFOEFS ‣ DBDIF͕ͳ͍ͱ͖͸ɺUISPXOFX1SPNJTF͢Δ  1SPNJTF͕SFTPMWF͞Ε͍ͯͳ͍৔߹͸SFOEFS͠ͳ͍  1SPNJTF͕SFTPMWF͞ΕͨΒ࠶SFOEFS 1SPNJTFΛUISPX 

Slide 12

Slide 12 text

©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

Something went wrong.

; } return this.props.children; } } ‣ ࢠίϯϙʔωϯτͷΤϥʔΛ਌ίϯϙʔωϯτͰ
 DBUDI͢Δ࢓૊Έ ‣ +4ͷDBUDIΈ͍ͨͳ͜ͱ͕$PNQPOFOUͰ
 Ͱ͖ΔΑ͏ʹͳΔ ‣ એݴతʹ͔͚Δ ‣ DPNQPOFOU%JE$BUDIͰัଊͰ͖Δ

Slide 13

Slide 13 text

©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

Something went wrong.

; } return this.props.children; } } ‣ ࢠίϯϙʔωϯτͷΤϥʔΛ਌ίϯϙʔωϯτͰ
 DBUDI͢Δ࢓૊Έ ‣ +4ͷDBUDIΈ͍ͨͳ͜ͱ͕$PNQPOFOUͰ
 Ͱ͖ΔΑ͏ʹͳΔ ‣ એݴతʹ͔͚Δ ‣ DPNQPOFOU%JE$BUDIͰัଊͰ͖Δ

Slide 14

Slide 14 text

©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

Something went wrong.

; } return this.props.children; } } ‣ ࢠίϯϙʔωϯτͷΤϥʔΛ਌ίϯϙʔωϯτͰ
 DBUDI͢Δ࢓૊Έ ‣ +4ͷDBUDIΈ͍ͨͳ͜ͱ͕$PNQPOFOUͰ
 Ͱ͖ΔΑ͏ʹͳΔ ‣ એݴతʹ͔͚Δ ‣ DPNQPOFOU%JE$BUDIͰัଊͰ͖Δ

Slide 15

Slide 15 text

©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

Something went wrong.

; } return this.props.children; } } ‣ ࢠίϯϙʔωϯτͷΤϥʔΛ਌ίϯϙʔωϯτͰ
 DBUDI͢Δ࢓૊Έ ‣ +4ͷDBUDIΈ͍ͨͳ͜ͱ͕$PNQPOFOUͰ
 Ͱ͖ΔΑ͏ʹͳΔ ‣ એݴతʹ͔͚Δ ‣ DPNQPOFOU%JE$BUDIͰัଊͰ͖Δ

Slide 16

Slide 16 text

©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 (
{results.slice(0, 5).map(result => { return ( ); })}
); }

Slide 17

Slide 17 text

©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 (
{results.slice(0, 5).map(result => { return ( ); })}
); }

Slide 18

Slide 18 text

©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 (
{results.slice(0, 5).map(result => { return ( ); })}
); }

Slide 19

Slide 19 text

©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 (
{results.slice(0, 5).map(result => { return ( ); })}
); }

Slide 20

Slide 20 text

©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 (
{results.slice(0, 5).map(result => { return ( ); })}
); } ͜͜ͰDBDIF͔Βऔͬͯ͘Δ

Slide 21

Slide 21 text

©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 (
{results.slice(0, 5).map(result => { return ( ); })}
); } DBDIF͕ͳ͔ͬͨΒUISPXOFX1SPNJTF

Slide 22

Slide 22 text

©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͕ͳ͔ͬͨΒ͜Μͳײ͡ʹͳΔ͸ͣ

Slide 23

Slide 23 text

©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͕ͳ͔ͬͨΒ͜Μͳײ͡ʹͳΔ͸ͣ

Slide 24

Slide 24 text

©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͕ͳ͔ͬͨΒ͜Μͳײ͡ʹͳΔ͸ͣ

Slide 25

Slide 25 text

©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 ( {didTimeout => ( {children} {didTimeout ? fallback : null} )} ); } export default Timeout;

Slide 26

Slide 26 text

©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 ( {didTimeout => ( {children} {didTimeout ? fallback : null} )} ); } export default Timeout;

Slide 27

Slide 27 text

©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 ( {didTimeout => ( {children} {didTimeout ? fallback : null} )} ); } export default Timeout;

Slide 28

Slide 28 text

©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 ( {didTimeout => ( {children} {didTimeout ? fallback : null} )} ); } export default Timeout;

Slide 29

Slide 29 text

©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 ( {didTimeout => ( {children} {didTimeout ? fallback : null} )} ); } export default Timeout;

Slide 30

Slide 30 text

©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 ( {didTimeout => ( {children} {didTimeout ? fallback : null} )} ); } export default Timeout;

Slide 31

Slide 31 text

©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 ( {didTimeout => ( {children} {didTimeout ? fallback : null} )} ); } export default Timeout;

Slide 32

Slide 32 text

©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 ( {didTimeout => ( {children} {didTimeout ? fallback : null} )} ); } export default Timeout;

Slide 33

Slide 33 text

©2018 Wantedly, Inc. "QPMMP$MJFOUͰ΋Ͱ͖Δʁ Page Title Page Subtitle

Slide 34

Slide 34 text

©2018 Wantedly, Inc. React Suspense on Apollo "TZOD.PEF const Photo = ({ breed }) => ( {({ data }) => { return ; }} ); ‣ ͳΜͯݺͿ͔͸Θ͔Βͳ͍ ‣ ࠷ॳ͸QSPQTͷ໊લ͕"TZD.PEFͩͬͨ ‣ 3FBDU"QPMMPͰϦϦʔε͢ΔΒ͍͠ ‣ "QPMMP$MJFOUͷ2VFSZ .VUBUJPOίϯ ϙʔωϯτͰ؆୯ʹඇಉظϨϯμϦϯά͕ Ͱ͖Δ

Slide 35

Slide 35 text

©2018 Wantedly, Inc. React Suspense on Apollo const Photo = ({ breed }) => ( {({ data }) => { return ; }} ); ‣ ͳΜͯݺͿ͔͸Θ͔Βͳ͍ ‣ ࠷ॳ͸QSPQTͷ໊લ͕"TZD.PEFͩͬͨ ‣ 3FBDU"QPMMPͰϦϦʔε͢ΔΒ͍͠ ‣ "QPMMP$MJFOUͷ2VFSZ .VUBUJPOίϯ ϙʔωϯτͰ؆୯ʹඇಉظϨϯμϦϯά͕ Ͱ͖Δ "TZOD.PEF

Slide 36

Slide 36 text

©2018 Wantedly, Inc. React Suspense on Apollo const Photo = ({ breed }) => ( {({ data }) => { return ; }} ); const Photo = ({ breed }) => ( {({ data, loading }) => { if (loading) return return ; }} ); ‣ ͳΜͯݺͿ͔͸Θ͔Βͳ͍ ‣ ࠷ॳ͸QSPQTͷ໊લ͕"TZD.PEFͩͬͨ ‣ 3FBDU"QPMMPͰϦϦʔε͢ΔΒ͍͠ ‣ "QPMMP$MJFOUͷ2VFSZ .VUBUJPOίϯ ϙʔωϯτͰ؆୯ʹඇಉظϨϯμϦϯά͕ Ͱ͖Δ "TZOD.PEF

Slide 37

Slide 37 text

©2018 Wantedly, Inc. React Suspense on Apollo const Photo = ({ breed }) => ( {({ data }) => { return ; }} ); const Photo = ({ breed }) => ( {({ data, loading }) => { if (loading) return return ; }} ); ‣ ͳΜͯݺͿ͔͸Θ͔Βͳ͍ ‣ ࠷ॳ͸QSPQTͷ໊લ͕"TZD.PEFͩͬͨ ‣ 3FBDU"QPMMPͰϦϦʔε͢ΔΒ͍͠ ‣ "QPMMP$MJFOUͷ2VFSZ .VUBUJPOίϯ ϙʔωϯτͰ؆୯ʹඇಉظϨϯμϦϯά͕ Ͱ͖Δ "TZOD.PEF

Slide 38

Slide 38 text

©2018 Wantedly, Inc. React Suspense on Apollo const Photo = ({ breed }) => ( {({ data }) => { return ; }} ); {expired => expired && selectedDog ? ( ) : ( ) } ‣ ͳΜͯݺͿ͔͸Θ͔Βͳ͍ ‣ ࠷ॳ͸QSPQTͷ໊લ͕"TZD.PEFͩͬͨ ‣ 3FBDU"QPMMPͰϦϦʔε͢ΔΒ͍͠ ‣ "QPMMP$MJFOUͷ2VFSZ .VUBUJPOίϯ ϙʔωϯτͰ؆୯ʹඇಉظϨϯμϦϯά͕ Ͱ͖Δ "TZOD.PEF

Slide 39

Slide 39 text

©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

Slide 40

Slide 40 text

©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

Slide 41

Slide 41 text

©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

Slide 42

Slide 42 text

©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

Slide 43

Slide 43 text

©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

Slide 44

Slide 44 text

©2018 Wantedly, Inc. ·ͱΊ ‣4VQFOTF͸3FBDUͰ࢖͑ΔΑ͏ʹͳΔ ‣"QPMMPͰͷ"TZOD3FOEFSJOH͸3FBDU"QPMMPͰ  EFGFS4FU4UBUFΛ࢖ͬͨ-PX1SJPSJUZͱ͔΋࢖͑Δ ‣IUUQTDPEFTBOECPYJPT[LYWL͜͜Ͱ3FBDU4VTQFOTF৮ΕΔ ‣IUUQTDPEFTBOECPYJPTWKYM͜͜Ͱ"QPMMPͷ"TZODSFOEFSJOHΛ ৮ΕΔ