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
Local State Management with Apollo
Search
Kodai Nakamura
August 23, 2018
Programming
1.6k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Local State Management with Apollo
Kodai Nakamura
August 23, 2018
More Decks by Kodai Nakamura
See All by Kodai Nakamura
React Fire
kdnk
2
1.5k
wejs24.pdf
kdnk
1
1.2k
React Suspense on Apollo
kdnk
4
1.6k
Other Decks in Programming
See All in Programming
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
21
6.9k
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
590
技術的負債解消で開発者の未来を開く- AIの力でコード刷新
kmd2kmd
0
110
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.3k
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
180
AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策
tnagao7
0
120
DynamoDBには集計系のクエリがないけどなんとかしたい
musan
1
180
Creating Composable Callables in Contemporary C++
rollbear
0
160
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
600
The NotImplementedError Problem in Ruby
koic
1
880
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
570
Lemonade + Foundry Toolkit でお手軽アプリ開発
seosoft
1
360
Featured
See All Featured
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.2k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
740
It's Worth the Effort
3n
188
29k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
400
Un-Boring Meetings
codingconduct
0
320
The untapped power of vector embeddings
frankvandijk
2
1.8k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
1.1k
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
The agentic SEO stack - context over prompts
schlessera
0
820
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
610
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.7k
Transcript
©2018 Wantedly, Inc. -PDBM4UBUF.BOBHFNFOU XJUI"QPMMP Roppongi.js #5 23th.Aug.2018 - Kodai
Nakamura
©2018 Wantedly, Inc. -PDBM4UBUF.BOBHFNFOU XJUI"QPMMP Roppongi.js #5 23th.Aug.2018 - Kodai
Nakamura
©2018 Wantedly, Inc. Kodai Nakamura Github: @kdnk Twitter: @kdnk__ Software
Engineer at Wantedly, inc. JavaScript, TypeScript, React, Rails, Ruby
©2018 Wantedly, Inc. (SBQI2-Ͱͷ4UBUF.BOBHFNFOU ʹ͍ͭͯ͠·͢
©2018 Wantedly, Inc. BQPMMPMJOLTUBUF
©2018 Wantedly, Inc. "QPMMPͰ4UBUFΛͲ͏ͬͯѻ͏͔ ‣ 3FEVYͱ͔.PC9ͱ͔Λ͏ ‣ "QPMMPʹ$BDIFͷΈ͕͋Δ ‣
6*ͷঢ়ଶ3FEVY αʔό͔Βऔ͖ͬͯͨσʔλ"QPMMPͷ$BDIF
©2018 Wantedly, Inc. ‣ 4UBUF͕ͭʹͳΔ z4JOHMFTPVSDFPGUSVUIz ‣ 4UBUFಉ࢜ͷ߹ΛऔΔͷ͕໘ ‣
σʔλͷߋ৽ํ๏͕ҧ͏ BDUJPOΛEJTQBUDIͯ͠SFEVDFS͕TUBUFΛߋ৽ RVFSZNVUBUJPO େมͦ͏ͳͱ͜Ζ
©2018 Wantedly, Inc. BQPMMPMJOLTUBUF ‣ (SBQI2-σʔλΛऔͬͯ͘ΔͨΊͷΫΤϦݴޠ ‣ ରαʔό͚ͩͰͳ͍ ‣ -PDBMͷσʔλͷߋ৽Λී௨ͷRVFSZNVUBUJPOͷΑ͏ʹߦ͑Δ
‣ 3FEVYͰ͍͏TUPSF͕BQPMMPͷDBDIF
©2018 Wantedly, Inc. BQPMMPMJOLTUBUF import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory'; import { ApolloLink } from 'apollo-link'; import { withClientState } from 'apollo-link-state'; import { HttpLink } from 'apollo-link-http'; import { defaults, resolvers } from './resolvers/todos'; const cache = new InMemoryCache(); const stateLink = withClientState({ resolvers, cache, defaults }); const client = new ApolloClient({ cache, link: ApolloLink.from([stateLink, new HttpLink()]), }); import { ApolloClient } from 'apollo-client'; import { HttpLink } from 'apollo-link-http'; import { InMemoryCache } from 'apollo-cache-inmemory'; const client = new ApolloClient({ link: new HttpLink(), cache: new InMemoryCache(), });
©2018 Wantedly, Inc. BQPMMPMJOLTUBUF import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory'; import { ApolloLink } from 'apollo-link'; import { withClientState } from 'apollo-link-state'; import { HttpLink } from 'apollo-link-http'; import { defaults, resolvers } from './resolvers/todos'; const cache = new InMemoryCache(); const stateLink = withClientState({ resolvers, cache, defaults }); const client = new ApolloClient({ cache, link: ApolloLink.from([stateLink, new HttpLink()]), }); import { ApolloClient } from 'apollo-client'; import { HttpLink } from 'apollo-link-http'; import { InMemoryCache } from 'apollo-cache-inmemory'; const client = new ApolloClient({ link: new HttpLink(), cache: new InMemoryCache(), }); ;ͭ͏ͷ"QPMMP
©2018 Wantedly, Inc. BQPMMPMJOLTUBUF import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory'; import { ApolloLink } from 'apollo-link'; import { withClientState } from 'apollo-link-state'; import { HttpLink } from 'apollo-link-http'; import { defaults, resolvers } from './resolvers/todos'; const cache = new InMemoryCache(); const stateLink = withClientState({ resolvers, cache, defaults }); const client = new ApolloClient({ cache, link: ApolloLink.from([stateLink, new HttpLink()]), }); import { ApolloClient } from 'apollo-client'; import { HttpLink } from 'apollo-link-http'; import { InMemoryCache } from 'apollo-cache-inmemory'; const client = new ApolloClient({ link: new HttpLink(), cache: new InMemoryCache(), }); ;ͭ͏ͷ"QPMMP
©2018 Wantedly, Inc. BQPMMPMJOLTUBUF import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory'; import { ApolloLink } from 'apollo-link'; import { withClientState } from 'apollo-link-state'; import { HttpLink } from 'apollo-link-http'; import { defaults, resolvers } from './resolvers/todos'; const cache = new InMemoryCache(); const stateLink = withClientState({ resolvers, cache, defaults }); const client = new ApolloClient({ cache, link: ApolloLink.from([stateLink, new HttpLink()]), }); import { ApolloClient } from 'apollo-client'; import { HttpLink } from 'apollo-link-http'; import { InMemoryCache } from 'apollo-cache-inmemory'; const client = new ApolloClient({ link: new HttpLink(), cache: new InMemoryCache(), }); BQPMMPMJOLTUBUFΛ͏ͱ͖
©2018 Wantedly, Inc. BQPMMPMJOLTUBUF import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory'; import { ApolloLink } from 'apollo-link'; import { withClientState } from 'apollo-link-state'; import { HttpLink } from 'apollo-link-http'; import { defaults, resolvers } from './resolvers/todos'; const cache = new InMemoryCache(); const stateLink = withClientState({ resolvers, cache, defaults }); const client = new ApolloClient({ cache, link: ApolloLink.from([stateLink, new HttpLink()]), }); import { ApolloClient } from 'apollo-client'; import { HttpLink } from 'apollo-link-http'; import { InMemoryCache } from 'apollo-cache-inmemory'; const client = new ApolloClient({ link: new HttpLink(), cache: new InMemoryCache(), }); BQPMMPMJOLTUBUFΛ͏ͱ͖
©2018 Wantedly, Inc. BQPMMPMJOLTUBUF import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory'; import { ApolloLink } from 'apollo-link'; import { withClientState } from 'apollo-link-state'; import { HttpLink } from 'apollo-link-http'; import { defaults, resolvers } from './resolvers/todos'; const cache = new InMemoryCache(); const stateLink = withClientState({ resolvers, cache, defaults }); const client = new ApolloClient({ cache, link: ApolloLink.from([stateLink, new HttpLink()]), }); import { ApolloClient } from 'apollo-client'; import { HttpLink } from 'apollo-link-http'; import { InMemoryCache } from 'apollo-cache-inmemory'; const client = new ApolloClient({ link: new HttpLink(), cache: new InMemoryCache(), }); BQPMMPMJOLTUBUFΛ͏ͱ͖
©2018 Wantedly, Inc. BQPMMPMJOLTUBUF import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory'; import { ApolloLink } from 'apollo-link'; import { withClientState } from 'apollo-link-state'; import { HttpLink } from 'apollo-link-http'; import { defaults, resolvers } from './resolvers/todos'; const cache = new InMemoryCache(); const stateLink = withClientState({ resolvers, cache, defaults }); const client = new ApolloClient({ cache, link: ApolloLink.from([stateLink, new HttpLink()]), }); import { ApolloClient } from 'apollo-client'; import { HttpLink } from 'apollo-link-http'; import { InMemoryCache } from 'apollo-cache-inmemory'; const client = new ApolloClient({ link: new HttpLink(), cache: new InMemoryCache(), }); BQPMMPMJOLTUBUFΛ͏ͱ͖
©2018 Wantedly, Inc. !DMJFOU BQPMMPMJOLTUBUF ‣ Ͳ͜ʹΫΤϦΛ͛Δ͔Λࣔ͢EJSFDUJWF ‣ ͜Ε͕͍͍ͭͯΔͱ MPDBMͷDBDIFʹରͯ͠ΫΤϦΛ͛Δ
const SET_VISIBILITY = gql` mutation SetFilter($filter: String!) { visibilityFilter(filter: $filter) @client } `; <Mutation mutation={SET_VISIBILITY}> {mutate => { return <>// ...</>; }} </Mutation>
©2018 Wantedly, Inc. !DMJFOU BQPMMPMJOLTUBUF const SET_VISIBILITY = gql` mutation
SetFilter($filter: String!) { visibilityFilter(filter: $filter) @client } `; <Mutation mutation={SET_VISIBILITY}> {mutate => { return <>// ...</>; }} </Mutation> ‣ Ͳ͜ʹΫΤϦΛ͛Δ͔Λࣔ͢EJSFDUJWF ‣ ͜Ε͕͍͍ͭͯΔͱ MPDBMͷDBDIFʹରͯ͠ΫΤϦΛ͛Δ
©2018 Wantedly, Inc. !DMJFOU BQPMMPMJOLTUBUF const SET_VISIBILITY = gql` mutation
SetFilter($filter: String!) { visibilityFilter(filter: $filter) @client } `; <Mutation mutation={SET_VISIBILITY}> {mutate => { return <>// ...</>; }} </Mutation> ‣ Ͳ͜ʹΫΤϦΛ͛Δ͔Λࣔ͢EJSFDUJWF ‣ ͜Ε͕͍͍ͭͯΔͱ MPDBMͷDBDIFʹରͯ͠ΫΤϦΛ͛Δ
©2018 Wantedly, Inc. EFGBVMUT BQPMMPMJOLTUBUF ‣ DBDIFͷॳظ ‣ SFEVYͩͱJOJUJBMTUBUF export
const defaults = { visibilityFilter: 'SHOW_ALL', todos: [], };
©2018 Wantedly, Inc. SFTPMWFST BQPMMPMJOLTUBUF ‣ "QPMMP4FSWFSͰɺ2VFSZ.VUBUJPOʹରԠ͢Δɺ ࣮ࡍʹσʔλΛऔಘ͢Δؔ ‣ BQPMMPMJOLTUBUFͰɺDBDIF͔ΒͷऔಘɾDBDIFʹର͢Δૢ࡞ͳͲ
ͷॲཧ͕هड़͞ΕΔͱ͜Ζ
©2018 Wantedly, Inc. SFTPMWFST export const resolvers = { Mutation:
{ visibilityFilter: (_, { filter }, { cache }) => { cache.writeData({ data: { visibilityFilter: filter } }); return null; }, addTodo: (_, { text }, { cache }) => { const query = gql` query GetTodos { todos @client { id text completed } } `; const previous = cache.readQuery({ query }); const newTodo = { id: nextTodoId++, text, completed: false, __typename: 'TodoItem', }; const data = { todos: previous.todos.concat([newTodo]), }; cache.writeData({ data }); return newTodo; }, } }
©2018 Wantedly, Inc. export const resolvers = { Mutation: {
visibilityFilter: (_, { filter }, { cache }) => { cache.writeData({ data: { visibilityFilter: filter } }); return null; }, addTodo: (_, { text }, { cache }) => { const query = gql` query GetTodos { todos @client { id text completed } } `; const previous = cache.readQuery({ query }); const newTodo = { id: nextTodoId++, text, completed: false, __typename: 'TodoItem', }; const data = { todos: previous.todos.concat([newTodo]), }; cache.writeData({ data }); return newTodo; }, } } SFTPMWFST
©2018 Wantedly, Inc. export const resolvers = { Mutation: {
visibilityFilter: (_, { filter }, { cache }) => { cache.writeData({ data: { visibilityFilter: filter } }); return null; }, addTodo: (_, { text }, { cache }) => { const query = gql` query GetTodos { todos @client { id text completed } } `; const previous = cache.readQuery({ query }); const newTodo = { id: nextTodoId++, text, completed: false, __typename: 'TodoItem', }; const data = { todos: previous.todos.concat([newTodo]), }; cache.writeData({ data }); return newTodo; }, } } SFTPMWFST
©2018 Wantedly, Inc. export const resolvers = { Mutation: {
visibilityFilter: (_, { filter }, { cache }) => { cache.writeData({ data: { visibilityFilter: filter } }); return null; }, addTodo: (_, { text }, { cache }) => { const query = gql` query GetTodos { todos @client { id text completed } } `; const previous = cache.readQuery({ query }); const newTodo = { id: nextTodoId++, text, completed: false, __typename: 'TodoItem', }; const data = { todos: previous.todos.concat([newTodo]), }; cache.writeData({ data }); return newTodo; }, } } SFTPMWFST
©2018 Wantedly, Inc. ·ͱΊ ‣ (SBQI2-MPDBMʹͳΔσʔλʹରͯ͛͠ΕΔ ‣ "QPMMP͚ͩͰ4BUFཧͰ͖Δ ‣ SFEVYͷϘΠϥʔϓϨʔτΛॻ͔ͳ͍͍͔ͯ͘ΒεοΩϦ͢Δ