阿波罗(Apollo)中的自动UI更新问题:`updateQuery`与`subscribeToMore`不能正常工作 [英] Issue with automatic UI updates in Apollo: `updateQuery` not working properly with `subscribeToMore`

查看:228
本文介绍了阿波罗(Apollo)中的自动UI更新问题:`updateQuery`与`subscribeToMore`不能正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为聊天应用程序使用 GraphQL订阅,但是UI更新存在问题.

I'm using GraphQL subscriptions for my chat application, but I have an issue with the UI updates.

这是我正在使用的查询和变异:

Here are the query and the mutation I'm using:

const createMessage = gql`
    mutation createMessage($text: String!, $sentById: ID!) {
        createMessage(text: $text, sentById: $sentById) {
            id
            text
        }
    }
`

const allMessages = gql`
    query allMessages {
        allMessages {
            id
            text
            createdAt
            sentBy {
                name
                location {
                    latitude
                    longitude
                }
            }
        }
    }
`

然后,在导出时,我将包裹Chat组件,如下所示:

Then, when exporting, I'm wrapping my Chat component like so:

export default graphql(createMessage, {name : 'createMessageMutation'})(
  graphql(allMessages, {name: 'allMessagesQuery'})(Chat)
)

我正在订阅componentDidMount中的allMessagesQuery:

componentDidMount() {

  // Subscribe to `CREATED`-mutations
  this.createMessageSubscription = this.props.allMessagesQuery.subscribeToMore({
    document: gql`
        subscription {
            Message(filter: {
                mutation_in: [CREATED]
            }) {
                node {
                    id
                    text
                    createdAt
                    sentBy {
                        name
                    }
                }
            }
        }
    `,
    updateQuery: (previousState, {subscriptionData}) => {
      console.log('Chat - received subscription: ', previousState, subscriptionData)
      const newMessage = subscriptionData.data.Message.node
      const messages = previousState.allMessages.concat([newMessage])
      console.log('Chat - new messages: ', messages.length, messages) // prints the correct array with the new message!!
      return {
        allMessages: messages
      }
    },
    onError: (err) => console.error(err),
  })

}

通过聊天发送消息后,订阅已成功触发,并且我看到两个日志记录语句也包含预期的数据.所以messages的内容在updateQuery内肯定是正确的!

After I sent the message through the chat, the subscription is triggered successfully and I see the two logging statements that also contain the expected data. So the contents of messages are definitely correct within updateQuery!

但是,UI不会自动更新,实际上,所有先前显示的消息都会消失.

However, the UI doesn't update automatically, in fact, all the previously displayed messages disappear.

我的render方法如下:

render() {
  console.log('Chat - render: ', this.props.allMessagesQuery)
  return (
    <div className='Chat'>
      <ChatMessages
        messages={this.props.allMessagesQuery.allMessages || []}
      />
      <ChatInput
        message={this.state.message}
        onTextInput={(message) => this.setState({message})}
        onResetText={() => this.setState({message: ''})}
        onSend={this._onSend}
      />
    </div>
  )
}

render中的日志记录语句显示,最初,this.props.allMessagesQuery具有数组allMessages,因此在初始加载后一切正常.

The logging statement in render shows that initially, this.props.allMessagesQuery has the array allMessages, so everything works after the initial loading.

收到订阅后,allMessagesthis.props.allMessagesQuery 中消失,这就是为什么将空数组赋给ChatMessages而没有呈现任何内容的原因.

After the subscription is received, allMessages disappears from this.props.allMessagesQuery which is why an empty array is given to ChatMessages and nothing is rendered.

在订阅被触发之前

订阅被触发后

推荐答案

我又一次浏览了文档后才发现,这是我的错误!

I figured it out after digging through the docs one more time, it was a mistake on my end!

Apollo文档的这一部分帮助我解决了该问题:

This part from the Apollo docs helped me solve the issue:

记住:您需要确保在每个需要标准化结果的查询中选择ID.

Remember: You'll need to ensure that you select IDs in every query where you need the results to be normalized.

因此,将id字段添加到我的查询和订阅返回的有效负载中实际上有所帮助.

So, adding the id fields to the returned payload of my queries and subscriptions actually helped.

const allMessages = gql`
    query allMessages {
        allMessages {
            id
            text
            createdAt
            sentBy {
                id
                name
                location {
                    id
                    latitude
                    longitude
                }
            }
        }
    }
`

subscription {
    Message(filter: {
        mutation_in: [CREATED]
    }) {
         node {
            id
            text
            createdAt
            sentBy {
                id
                name
            }
        }
    }
}

这篇关于阿波罗(Apollo)中的自动UI更新问题:`updateQuery`与`subscribeToMore`不能正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆