Apollo Client Write Query Not Updating UI

前端 未结 2 1815
悲&欢浪女
悲&欢浪女 2021-01-05 09:13

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

2条回答
  •  逝去的感伤
    2021-01-05 10:04

    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 (
              
    { e.preventDefault() addPost({variables: { post: postInput }}) }}> (setPostInput(e.target.value))} />
    ) }}
    ) } export default PostInput

自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题