readQuery는 cache에 있는 query를 가져옵니다.
writeQuery는 query를 cache하게 됩니다.
시나리오는 다음과 같습니다.
job list를 홈페이지에서 가져오고, 유저가 새로운 job을 포스팅하려고 합니다. 포스팅과정에서 현재 cache되어 있는 job list를 가져오고 싶습니다.
하지만 mutation.js의 readQuery결과값은 null으로 나타났습니다. 분명 job list를 먼저 가져왔기 때문에 cache되어있는 값이 읽혀야 합니다.
// query.js
const client = new ApolloClient({
uri: GRAPHQL_REQUEST,
cache: new InMemoryCache(),
headers: {
authorization: token ? `Bearer ${token}` : "",
},
})
const QUERY_JOBS = gql`
{
jobs {
id
title
company {
id
name
description
}
}
}
`
// #1. job list를 query하여, cache에 저장되었습니다.
export async function getJobs(id) {
const { data: { jobs } } = await client.query({ query: QUERY_JOBS });
return jobs;
}
// mutation.js
const client = new ApolloClient({
uri: GRAPHQL_REQUEST,
cache: new InMemoryCache(),
headers: {
authorization: token ? `Bearer ${token}` : "",
},
})
const QUERY_JOBS = gql`
{
jobs {
id
title
company {
id
name
description
}
}
}
`
export async function createJob({ title, description, companyId }) {
const mutation = gql`
mutation CreateJob($input: CreateJobInput!) {
job: createJob(input: $input) {
id
title
description
company {
id
name
description
}
}
}
`
const variables = { input: { title, description, companyId } }
const { data: { job } } = await client.mutate({
mutation,
variables,
update: async (cache, { data: { job } }) => {
// #2. job을 POST하면서, cache되어있던 job list를 가져오려고 합니다.
const read = await client.readQuery({
query: QUERY_JOBS,
})
// 하지만 결과는 null 입니다.
console.log('read::', read);
}
});
return job;
}
ApolloClient의 인스턴스를 각 파일마다 생성한 것이 문제가 되었습니다. InMemoryCache는 각각의 인스턴스에 적용됩니다.(즉 인스턴스마다 cache가 있습니다.) 따라서 ApolloClient의 인스턴스는 root파일에 한번만 생성하고, import하여 사용하여야 합니다.
실제로 ApolloClient의 Docs를 보면 ApolloProvider에 client props에 생성한 인스턴스를 넣어주고 있습니다. (Docs 참고)
const client = new ApolloClient({
cache: new InMemoryCache(),
uri: "http://localhost:4000/graphql"
});
ReactDOM.render(
<ApolloProvider client={client}>
<MyRootComponent />
</ApolloProvider>,
document.getElementById('root'),
);
너무 당연하지만, 이런실수를 하지 않도록 인스턴스 생성시 유의해야하겠습니다.
이 원인을 찾는데에 3시간을 삽질하였습니다.
끝.