问题描述
我正在为聊天应用程序使用 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.
收到订阅后,allMessages
从this.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
字段添加到我的查询和订阅返回的有效负载中实际上有所帮助.
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`不能正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!