【问题标题】:Apollo graphql: writeQuery after mutation does not trigger re-render of flatlistApollo graphql:突变后的writeQuery不会触发平面列表的重新渲染
【发布时间】:2018-08-12 15:44:33
【问题描述】:

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

   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
        }
      },
    }
    }`;

【问题讨论】:

  • 你能把你定义查询操作的代码贴出来并连接到平面列表吗?
  • @TalZ 我已经添加了您请求的代码,其中包含我的查询操作以及它如何连接到平面列表。

标签: react-native graphql apollo apollo-client


【解决方案1】:

我认为 Apollo 在决定更改后应触发哪个查询侦听器时会考虑一些因素,包括 variables 字段。

在您的情况下,您的带有平面列表的组件不会重新呈现,因为查询没有收到更改通知。它不会收到更改通知,因为 Apollo 认为这是与您在调用 writeQuery 时在商店中更新的查询不同的查询。

所以解决方法是在调用writeQuery时添加variables字段。它应该与调用查询时使用的值相同。

假设这些具有正确的值,您对store.writeQuery 的调用应该如下所示:

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

【讨论】:

  • 这很有趣。我花了几个小时试图解决这个问题,但没有可能的解释。我不会想到再次指定变量,特别是当我已经在“readQuery”中注意到它们时。哦,生活和学习。点赞!
  • 感谢和新年快乐(来自亚洲)
  • 谢谢,这行得通,但我真的不知道为什么会这样
  • 因为缺少变量参数而耽误了我的一天 ?
猜你喜欢
  • 2018-03-05
  • 2021-06-20
  • 2019-12-05
  • 2020-03-13
  • 2020-10-14
  • 2019-10-03
  • 2019-02-02
  • 2021-01-23
  • 1970-01-01
相关资源
最近更新 更多