簡體   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