We are building an offline first React Native Application with Apollo Client. Currently I am trying to update the Apollo Cache directly when offline to update the UI optimis
Just to save someones time. Using the data in an immutable way was the solution. Agree totally with this answer, but for me I did something else wrong and will show it here. I followed this tutorial and updating the cache worked fine as I finished the tutorial. So I tried to apply the knowledge in my own app, but there the update didn’t work even I did everything similar as showed in the tutorial.
Here was my approach to update the data using the state to access it in the render method:
// ... imports
export const GET_POSTS = gql`
query getPosts {
posts {
id
title
}
}
`
class PostList extends Component {
constructor(props) {
super(props)
this.state = {
posts: props.posts
}
}
render() {
const postItems = this.state.posts.map(item => )
return (
{postItems}
)
}
}
const PostListQuery = () => {
return (
{({ loading, error, data }) => {
if (loading) {
return (Loading...)
}
if (error) {
console.error(error)
}
return ()
}}
)
}
export default PostListQuery
The solution was just to access the date directly and not using the state at all. See here:
class PostList extends Component {
render() {
// use posts directly here in render to make `cache.writeQuery` work. Don't set it via state
const { posts } = this.props
const postItems = posts.map(item => )
return (
{postItems}
)
}
}
Just for completeness here is the input I used to add a new post and update the cache:
import React, { useState, useRef } from 'react'
import gql from 'graphql-tag'
import { Mutation } from 'react-apollo'
import { GET_POSTS } from './PostList'
const ADD_POST = gql`
mutation ($post: String!) {
insert_posts(objects:{title: $post}) {
affected_rows
returning {
id
title
}
}
}
`
const PostInput = () => {
const input = useRef(null)
const [postInput, setPostInput] = useState('')
const updateCache = (cache, {data}) => {
// Fetch the posts from the cache
const existingPosts = cache.readQuery({
query: GET_POSTS
})
// Add the new post to the cache
const newPost = data.insert_posts.returning[0]
// Use writeQuery to update the cache and update ui
cache.writeQuery({
query: GET_POSTS,
data: {
posts: [
newPost, ...existingPosts.posts
]
}
})
}
const resetInput = () => {
setPostInput('')
input.current.focus()
}
return (
{(addPost, { loading, data }) => {
return (
)
}}
)
}
export default PostInput