0

チャット アプリケーションに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),
  })

}

チャットを介してメッセージを送信した後、サブスクリプションが正常にトリガーされ、予想されるデータも含まれている 2 つのログ ステートメントが表示されます。したがって、 の内容は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は arrayallMessagesを持っていることを示しているため、最初の読み込み後にすべてが機能します。

サブスクリプションを受け取った後、 がallMessages消えthis.props.allMessagesQueryます。そのため、空の配列が渡されChatMessages、何もレンダリングされません。

サブスクリプションがトリガーされる前に✅</p>

ここに画像の説明を入力

サブスクリプションがトリガーされた後❌</p>

ここに画像の説明を入力

4

2 に答える 2