A presentation at GraphQL Day in in Berlin, Germany by Sara Vieira
!
@NIkkitaFTW GQL ALL THE THINGS
@NIkkitaFTW
MANAGING LOCAL
STATE WITH APOLLO
@NIkkitaFTW MY NAME IS SARA
@NikkitaFTW Developer Advocate at YLD Really into shitty movies
Really into football please y’all need to watch troll 2
@NIkkitaFTW LIVES IN THE MIDDLE OF NOWHERE
@NIkkitaFTW ALERT
@NIkkitaFTW I DON’T LIKE REDUX Dan is great tho …
@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.
@NIkkitaFTW WHY?
@NIkkitaFTW GQL ALL THE THINGS
@NIkkitaFTW HOW?
@NIkkitaFTW FIRST… APOLLO BOOST
@NIkkitaFTW REMEMBER THIS ?
@NIkkitaFTW I CAN’T REMEMBER THIS
@NIkkitaFTW NOW:
import React from
' react ';
import ApolloClient from
boost ';
import { ApolloProvider } from
apollo ';
import Main from
' ./Main '
new ApolloClient({
"# YOUR STUFF
}) ;
const
App
=
()
"$ (
< ApolloProvider
client= { client }>
<
Main
"%
"& ApolloProvider
)
@NIkkitaFTW DONE!
@NIkkitaFTW GOD BLESS PEGGY RAYZIS
@NIkkitaFTW NOW STATE
export
new ApolloClient({
uri :
graphql.now.sh/graphql ' ,
clientState : {
defaults ,
resolvers
}
})
const
App
=
()
"$ (
< ApolloProvider
client= { client }>
<
Main
"%
"& ApolloProvider
)
What ? What ?
@NIkkitaFTW DEFAULTS Your base state. What you start with
export
{
modal : {
modalIsOpen :
false ,
"' typename :
' modal '
}
}
@NIkkitaFTW RESOLVERS This is here all the magic happens to retrieve and update your local data in the Apollo cache
export
{
Mutation : {
openModal : ( _, params, { cache } )
"$ {
{
modal : {
modalIsOpen :
true ,
"' typename :
" modal "
}
}
;
cache
. writeData ({ data }) ; return null;
}
}
} ;
@NIkkitaFTW THE MUTATION You know … The GQL part of the equation
import { gql } from
boost '
export
default
gql `
mutation
openModal
{
openModal
@client
}
`
@NIkkitaFTW THE QUERY You know … The GQL part of the equation
import { gql } from
boost ";
export
default
gql `
{
modal
@client
{
modalIsOpen
}
}
`;
@NIkkitaFTW WE MADE THE BEHIND THE SCENES How do you actually call these things ?
@NIkkitaFTW
THE QUERY
COMPONENT
import React from
" react ";
import Modal from
modal ";
import { Query } from
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?
@NIkkitaFTW CAN WE MAKE THIS SMALLER?
@NIkkitaFTW HELL YEAH LET’S CREATE OUR VERY OWN QUERY COMPONENT
import React from
" react ";
import { Query } from
apollo ";
export
default
( { children, ""( props } )
"$ (
< Query { ""( props }>
{({
loading , error , data }) "$ {
if (
loading ) { return ' loading ' };
if (
error ) return
Error!: ${ error }
;
return
children( data ) ;
}}
"& Query
) ;
@NIkkitaFTW OUR CODE NOW:
import React from
" react ";
import Modal from
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
) ;
@NIkkitaFTW FITS IN ONE SLIDE
@NIkkitaFTW BUT NO MODAL :(
@NIkkitaFTW
THE MUTATION
COMPONENT
import React from
" react ";
import { Mutation } from
apollo ";
import { OPEN_MODAL } from
" ") /queries/ ";
export
default
()
"$ (
< Mutation
mutation= { OPEN_MODAL }>
{
openModal
"$ (
<
button
onClick= { openModal }>
Wait
""( Everyone loves modals right ?
"& button
)}
"& Mutation
) ; Wat?
@NIkkitaFTW STILL THINK IT’S TOO MUCH CODE ?
@NIkkitaFTW APOLLO CONSUMER Used for very simple mutations to the cache
import React from
" react ";
import { ApolloConsumer } from
apollo ";
export
default
()
"$ (
< ApolloConsumer
{
cache
"$ (
<
button
onClick= {() "$ cache . writeData ({
data : { modal : { isOpen : true } }
})}
>
Wait
""( Everyone loves modals right ?
"& button
)}
"& ApolloConsumer
) ;
@NIkkitaFTW WHERE IS THE MUTATION? It’s done on the fly ! No need to define it before "
@NIkkitaFTW CAN YOU MAKE THE QUERY AND MUTATION IN ONE SLIDE ME
@NIkkitaFTW HOLD MY BEER
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
) ;
@NIkkitaFTW THE MODAL DOES NOT CLOSE
@NIkkitaFTW FINE…
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
) ;
@NIkkitaFTW FUTURE
@NIkkitaFTW TYPE CHECKING
@NIkkitaFTW HELPER COMPONENTS
@NIkkitaFTW DEMOS
@NIkkitaFTW DEMO: CODESANDBOX.IO/S/4X2PLK2V3W
@NIkkitaFTW DEMO WITH VARIABLES AND REMOTE DATA: CODESANDBOX.IO/S/O5Z5O9VRP9
@NIkkitaFTW VUE? HTTPS://APOLLO-VUE-LOVE.NOW.SH/
THANK YOU
https://link-state-is-dope.now.sh/