繁体   English   中英

阿波罗(Apollo)中的自动UI更新问题:`updateQuery`与`subscribeToMore`无法正常工作

[英]Issue with automatic UI updates in Apollo: `updateQuery` not working properly with `subscribeToMore`

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

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

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组件,如下所示:

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

我订阅了allMessagesQuerycomponentDidMount

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中绝对正确!

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

我的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 ,因此在初始加载后一切正常。

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

在触发订阅之前

在此处输入图片说明

订阅触发后

在此处输入图片说明

我再研究了一次文档后才发现,这是我的错误!

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

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

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

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
            }
        }
    }
}

在您的更新查询中,previousState是allMessages查询,该查询保存在react apollo存储中。

要更新商店,您必须进行深拷贝或使用一些帮助程序,例如, 反应不变性帮助程序 阿波罗开发人员页面提供了一些有关如何正确更新商店的信息Query

在您的情况下,它可能看起来像这样

 ... updateQuery: (previousState, { subscriptionData }) => { const newMessage = subscriptionData.data.Message.node; return update(previousState, { allMessages: { $push: [newMessage] }, }); } ... 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM