State Management in React Apps with Apollo Client

A presentation at GraphQL Day in April 2018 in Berlin, Germany by Sara Vieira

Slide 1

Slide 1

!

Slide 2

Slide 2

@NIkkitaFTW GQL ALL THE THINGS

Slide 3

Slide 3

@NIkkitaFTW MANAGING LOCAL
STATE WITH APOLLO

Slide 4

Slide 4

Slide 5

Slide 5

@NIkkitaFTW MY NAME IS SARA

Slide 6

Slide 6

@NikkitaFTW Developer Advocate at YLD Really into shitty movies

Really into football please y’all need to watch troll 2

Slide 7

Slide 7

@NIkkitaFTW LIVES IN THE MIDDLE OF NOWHERE

Slide 8

Slide 8

@NIkkitaFTW ALERT

Slide 9

Slide 9

@NIkkitaFTW I DON’T LIKE REDUX Dan is great tho …

Slide 10

Slide 10

@NIkkitaFTW • We got this awesome React project that is all Apollo and GraphQL, want to help? • That sounds awesome. What do you use for state management? • Redux.

Slide 11

Slide 11

@NIkkitaFTW WHY?

Slide 12

Slide 12

@NIkkitaFTW GQL ALL THE THINGS

Slide 13

Slide 13

Slide 14

Slide 14

Slide 15

Slide 15

@NIkkitaFTW HOW?

Slide 16

Slide 16

@NIkkitaFTW FIRST… APOLLO BOOST

Slide 17

Slide 17

@NIkkitaFTW REMEMBER THIS ?

Slide 18

Slide 18

Slide 19

Slide 19

@NIkkitaFTW I CAN’T REMEMBER THIS

Slide 20

Slide 20

@NIkkitaFTW NOW:

Slide 21

Slide 21

Slide 22

Slide 22

import React from

' react ';

import ApolloClient from

' apollo

boost ';

import { ApolloProvider } from

' react

apollo ';

import Main from

' ./Main '

const client

new ApolloClient({

"# YOUR STUFF

}) ;

const

App

=

()

"$ (

< ApolloProvider

client= { client }>

    <

Main

"%

"& ApolloProvider

)

Slide 23

Slide 23

@NIkkitaFTW DONE!

Slide 24

Slide 24

@NIkkitaFTW GOD BLESS PEGGY RAYZIS

Slide 25

Slide 25

Slide 26

Slide 26

@NIkkitaFTW NOW STATE

Slide 27

Slide 27

export

const client

new ApolloClient({

uri :

' https: "# figma

graphql.now.sh/graphql ' ,

clientState : {

defaults ,

resolvers

}

})

const

App

=

()

"$ (

< ApolloProvider

client= { client }>

    <

Main

"%

"& ApolloProvider

)

What ? What ?

Slide 28

Slide 28

@NIkkitaFTW DEFAULTS Your base state. What you start with

Slide 29

Slide 29

export

const defaults

{

modal : {

modalIsOpen :

false ,

"' typename :

' modal '

}

}

Slide 30

Slide 30

@NIkkitaFTW RESOLVERS This is here all the magic happens to retrieve and update your local data in the Apollo cache

Slide 31

Slide 31

export

const resolvers

{

Mutation : {

openModal : ( _, params, { cache } )

"$ {

const data

{

modal : {

modalIsOpen :

true ,

"' typename :

" modal "

            }

        }

;

        cache

. writeData ({ data }) ; return null;

    }

}

} ;

Slide 32

Slide 32

@NIkkitaFTW THE MUTATION You know … The GQL part of the equation

Slide 33

Slide 33

import { gql } from

' apollo

boost '

export

default

gql `

mutation

openModal

{

openModal 

@client

}

`

Slide 34

Slide 34

@NIkkitaFTW THE QUERY You know … The GQL part of the equation

Slide 35

Slide 35

import { gql } from

" apollo

boost ";

export

default

gql `

{

modal 

@client

{

  modalIsOpen

}

}

`;

Slide 36

Slide 36

@NIkkitaFTW WE MADE THE BEHIND THE SCENES How do you actually call these things ?

Slide 37

Slide 37

@NIkkitaFTW THE QUERY
COMPONENT

Slide 38

Slide 38

import React from

" react ";

import Modal from

" react

modal ";

import { Query } from

" react

apollo ";

import { GET_MODAL } from

" ./queries/ ";

export

default

()

"$ (

< div

    <

Query

query= { GET_MODAL }>

        {({ 

loading , error , modal : { modalIsOpen } }) "$ {

            if (

loading ) {

                return "

loading man ""( Chill ""( ";

            }

            if (

error ) return

Error!: ${ error };

            return (

                <

Modal

isOpen= { modalIsOpen }>

                    <

h1

Of course they do ""(

"& h1

"& Modal

            );

        }}

    

"& Query

"& div

) ; Wat?

Slide 39

Slide 39

@NIkkitaFTW CAN WE MAKE THIS SMALLER?

Slide 40

Slide 40

@NIkkitaFTW HELL YEAH LET’S CREATE OUR VERY OWN QUERY COMPONENT

Slide 41

Slide 41

import React from

" react ";

import { Query } from

" react

apollo ";

export

default

( { children, ""( props } )

"$ (

< Query { ""( props }>

    {({ 

loading , error , data }) "$ {

        if (

loading ) { return ' loading ' };

        if (

error ) return

Error!: ${ error };

        return

children( data ) ;

    }}

"& Query

) ;

Slide 42

Slide 42

@NIkkitaFTW OUR CODE NOW:

Slide 43

Slide 43

import React from

" react ";

import Modal from

" react

modal ";

import { Query } from

" ./components/ ";

import { GET_MODAL } from

" ./queries/ ";

export

default

()

"$ (

< div

    <

Query

query= { GET_MODAL }>

        {({ 

modal : { modalIsOpen } }) "$ (

            <

Modal

isOpen= { modalIsOpen }>

                <

h1

Of course they do ""(

"& h1

"& Modal

        )}

    

"& Query

"& div

) ;

Slide 44

Slide 44

@NIkkitaFTW FITS IN ONE SLIDE

Slide 45

Slide 45

Slide 46

Slide 46

@NIkkitaFTW BUT NO MODAL :(

Slide 47

Slide 47

@NIkkitaFTW THE MUTATION
COMPONENT

Slide 48

Slide 48

import React from

" react ";

import { Mutation } from

" react

apollo ";

import { OPEN_MODAL } from

" ") /queries/ ";

export

default

()

"$ (

< Mutation

mutation= { OPEN_MODAL }>

    {

openModal

"$ (

        <

button

onClick= { openModal }>

            Wait

""( Everyone loves modals right ?

"& button

    )}

"& Mutation

) ; Wat?

Slide 49

Slide 49

@NIkkitaFTW STILL THINK IT’S TOO MUCH CODE ?

Slide 50

Slide 50

@NIkkitaFTW APOLLO CONSUMER Used for very simple mutations to the cache

Slide 51

Slide 51

import React from

" react ";

import { ApolloConsumer } from

" react

apollo ";

export

default

()

"$ (

< ApolloConsumer

    {

cache

"$ (

        <

button

onClick= {() "$ cache . writeData ({

data : { modal : { isOpen : true } }

        })}

        >

            Wait

""( Everyone loves modals right ?

"& button

    )}

"& ApolloConsumer

) ;

Slide 52

Slide 52

@NIkkitaFTW WHERE IS THE MUTATION? It’s done on the fly ! No need to define it before "

Slide 53

Slide 53

@NIkkitaFTW CAN YOU MAKE THE QUERY AND MUTATION IN ONE SLIDE ME

Slide 54

Slide 54

@NIkkitaFTW HOLD MY BEER

Slide 55

Slide 55

const

MODAL

=

gql `

{

modalOpen 

@client

}

`;

export

default

()

"$ (

< Query

query= { MODAL }>

    {({ 

data , client }) "$ (

        <

Fragment

            <

button

onClick= {() "$

                    client

. writeData ({

data : { modalOpen : true }

                    });

                }

            >

                A MODAL

            

"& button

            <

Modal

isOpen= { data . modalOpen }>YEAH SON "& Modal

"& Fragment

    )}

"& Query

) ;

Slide 56

Slide 56

@NIkkitaFTW THE MODAL DOES NOT CLOSE

Slide 57

Slide 57

@NIkkitaFTW FINE…

Slide 58

Slide 58

const

changeState

=

( client, value )

"$

client

. writeData ({

data : { modalOpen : value }

})

;

export

default

()

"$ (

< Query

query= { MODAL }>

  {({ 

data , client }) "$ (

      <

Fragment

          <

button

onClick= {() "$ changeState( client , true ) }>A MODAL "& button

          <

Modal

isOpen= { data . modalOpen }

onRequestClose= {() "$ changeState( client , false ) }>

                YEAH SON

            

"& Modal

"& Fragment

    )}

"& Query

) ;

Slide 59

Slide 59

@NIkkitaFTW FUTURE

Slide 60

Slide 60

@NIkkitaFTW TYPE CHECKING

Slide 61

Slide 61

@NIkkitaFTW HELPER COMPONENTS

Slide 62

Slide 62

@NIkkitaFTW DEMOS

Slide 63

Slide 63

@NIkkitaFTW DEMO: CODESANDBOX.IO/S/4X2PLK2V3W

Slide 64

Slide 64

@NIkkitaFTW DEMO WITH VARIABLES AND REMOTE DATA: CODESANDBOX.IO/S/O5Z5O9VRP9

Slide 65

Slide 65

@NIkkitaFTW VUE? HTTPS://APOLLO-VUE-LOVE.NOW.SH/

Slide 66

Slide 66

Slide 67

Slide 67

THANK YOU

https://link-state-is-dope.now.sh/