Apollo graphql:变异后的writeQuery不会触发flatlist的重新渲染

时间:2018-03-05 02:49:04

标签: react-native graphql apollo apollo-client

我在平面列表中有以下按钮触发graphql变异,在变异之后我执行writeQuery来更新本地缓存(store)。在更新函数f中,我正在更新缓存中的两个字段。基本上当用户触摸类似按钮时,我将类似的布尔值变为true,并将该帖子的类似计数更新为+1(类似于twitter)。但是,平面列表中的组件不会更新。我甚至打印出了apollo商店/缓存,我看到值得到了更新。为什么在缓存写入后平面列表不能重新渲染?

   render() {


 const { posts, isFetching, lastUpdated, location, navigation, data, likeMutation, username, distancePointLatitude, distancePointLongitude, searchPointLatitude, searchPointLongitude } = this.props


 <FlatList
  data={data.near}
  style={styles.scrollViewContent}
  extraData={this.props.store}
  //renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
  showsVerticalScrollIndicator={false}
  onRefresh={this._onRefresh.bind(this)}
  refreshing={this.state.refreshing}
  keyExtractor={this._keyExtractor}
  renderItem={({item, index}) => item.posts.length != 0 && <ListItem>

{item.posts[0].userInteraction.userLike ? <Icon name='md-heart' style={{ color: 'crimson',fontSize: 28}} /> 
          : <Icon name='heart' style={{ fontSize: 26}} 

          onPress={() => likeMutation({ variables: { elementId: item.posts[0].postId, userId: username  },

            update: (store, { data: { addLike } }) => {
              // Read the data from our cache for this query.

              var thisLocationRadius = {searchPointLongitude: searchPointLongitude,
                searchPointLatitude: searchPointLatitude,
                radius: fiftyMilesInMeters, distancePointLongitude: distancePointLongitude,
                 distancePointLatitude: distancePointLatitude };


              var data = store.readQuery({ query: getLocalPosts,
                variables: {
                locationRadius: thisLocationRadius,
                userId: username
              }, });


             data.near[index].posts[0].userInteraction.userLike = true

              data.near[index].posts[0].interactionStats.totalLikes + 1


              // Write our data back to the cache.
              store.writeQuery({ query: getLocalPosts, data });



            },
          }).catch((error) => {
          console.log('there was an error sending the query', error);
          })} />  }
}

  const HomeWithData = graphql(getLocalPosts, {
        options:  ({ searchPointLongitude, searchPointLatitude, distancePointLongitude, distancePointLatitude, username }) => ({ variables: { locationRadius: {searchPointLongitude: searchPointLongitude,
           searchPointLatitude: searchPointLatitude,
           radius: fiftyMilesInMeters, distancePointLongitude: distancePointLongitude,
            distancePointLatitude: distancePointLatitude }, userId: username } }),

        });


export default compose( connect(mapStateToProps),
HomeWithData,
graphql(like, { name: 'likeMutation' }))(Home);

getLocalPosts查询:

export const getLocalPosts = gql`query getLocalPosts($locationRadius: locationRadius!, , $userId: String!) {
    near(locationRadius: $locationRadius){
      name,
      address,
      phonenumber,
      email,
      website,
      about,
      location {
        longitude,
        latitude
      },
      distance(unit: MILE),
      businessId,
      hours {
        weekDay,
        startTime,
        endTime
      },
      posts(isActive: true) {
        postText,
        postId,
        userInteraction(userId: $userId){
          userLike
        },
        interactionStats{
          totalLikes
        }
      },
    }
    }`;

1 个答案:

答案 0 :(得分:10)

I think that Apollo takes into account a few things when it decides which query listener should be triggered after a change, including the variables field.

In your case, your component with the flat list is not re-rendered because the query isn't notified of a change. It isn't notified of a change because Apollo thinks it is a different query than the one you are updating in the store when you call writeQuery.

So the solution is to add the variables field when you call writeQuery. And it should have the same values you use when the query is called.

Assuming these have the correct values, your call to store.writeQuery should look something like this:

          store.writeQuery({ 
            query: getLocalPosts, 
            data, 
            variables: {
              locationRadius: thisLocationRadius,
              userId: username
            }
          });