【问题标题】:Issue with automatic UI updates in Apollo: `updateQuery` not working properly with `subscribeToMore`Apollo 中的自动 UI 更新问题:`updateQuery` 不能与 `subscribeToMore` 一起正常工作
【发布时间】:2017-07-18 11:46:57
【问题描述】:

我正在为我的聊天应用程序使用 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)
)

我在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内肯定是正确的!

但是,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 一个空数组而没有渲染的原因。

订阅触发前

订阅触发后

【问题讨论】:

    标签: javascript graphql apollo apollostack react-apollo


    【解决方案1】:

    我又翻了一遍文档才发现,这是我的错误!

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

    请记住:您需要确保在需要对结果进行规范化的每个查询中选择 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
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

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

      要更新商店,您必须进行深层复制或使用一些帮助程序,例如reacts immutability helper。 apollo 开发者页面提供了一些关于如何正确更新商店的信息update Query

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

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

      【讨论】:

        猜你喜欢
        • 2014-10-19
        • 2019-12-29
        • 2017-08-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-10
        • 2014-07-01
        • 1970-01-01
        • 2016-07-19
        相关资源
        最近更新 更多