サブスクリプションとリアルタイム更新の一般的なアプローチを理解するには、何か助けが必要です。私はReact Nativeアプリを持っていて、ApolloとGraphcoolサービスをバックエンドとして使っています。Reactアプリケーションでサブスクリプションにアクセスする方法
アプリを見ているユーザーが何か変わったというプッシュ通知を受け取るシナリオがいくつかあります。もちろん、画面データも更新されるはずです。サブスクリプションはその仕事の明白な候補者であり、本質的に働いています。
私はこのようなサブスクリプションを持っています。これは、単独でうまく動作します(Googleマップ上でプレイヤーのアバターを配置するために使用されます)。
subscription PlayerMap($gameId: ID) {
Game(filter: { mutation_in: [CREATED, UPDATED], node: { id: $gameId } }) {
node {
players {
id
character {
id
name
}
user {
id
latitude
longitude
}
}
}
}
}
そしてものを更新するには、このクエリを実行する(簡単にするために)アポロからrefetchQueries
と共に突然変異createPlayer
を実行する別のアプリ画面があります。これが完了すると
query GameCharacters($gameId: ID!) {
Game(id: $gameId) {
players {
id
character {
id
name
}
}
}
}
は今、サブスクリプションクエリが(それは別の画面上でまだアクティブである)も更新されますが、何らかの理由で全体Game
ノードがdata
オブジェクトにありません。
サブスクリプションを処理するために、私はこのようなコンポーネントを持っています。
class Subscriber extends Component<void, Props, void> {
componentDidMount() {
this.subscribe()
}
componentWillReceiveProps({ data, shouldResubscribe }) {
if (this.unsubscribe) {
if (shouldResubscribe && shouldResubscribe(data, this.props.data) !== true) {
return
}
this.unsubscribe()
}
this.subscribe()
}
subscribe() {
const { data, query, variables } = this.props
this.unsubscribe = data.subscribeToMore({
document: query,
variables,
})
}
unsubscribe: ?Function = null
render() {
return this.props.children(this.props.data)
}
}
このようにレンダリングパターンを使用すると簡単に使用できます。
const OrgMapScreen = ({ gameId, data: initialData }: Props) => (
<Subscriber
data={initialData}
query={OrgMapSubscription}
variables={{ gameId }}
shouldResubscribe={(nextData, prevData) => nextData.Game !== prevData.Game}
>
{({ Game }) => {
const markers = Game.players.map(makePlayerMarker)
return <MapScreen mapProps={{ markers }} />
}}
</Subscriber>
)
なぜそれが起こっているのですか?そのようなものをどう扱うのか、お勧めの方法はありますか?おそらくrefetchQueries
の代わりにGameCharacters
の別のサブスクリプションも設定する必要がありますか?
「updateQuery」はちょっと必要です。なぜ私は、Apolloが型と 'dataIdFromObject'に基づいて独自の結果ストアを更新するという印象を得たのか分かりません。しかたがない。私のような深く入れ子構造に '不変ヘルパー 'を使用しなければならなかったのですが、今のところうまくいくようです。ありがとう – FredyC