2017-12-12 5 views
1

Apolloクライアント(バージョン1.x)を使用してGraphQLサーバーにアクセスするReactアプリケーションがあります。このようなサーバースキーマがあります。Apollo GraphQLでのrefetchQueriesの使用を避けることはできますか?

type Query { 
    currentShop: Shop 
} 
type Shop { 
    id: ID! 
    name: String! 
    products: [Product!]! 
    ...etc 
} 

私はdataIdFromObjectがこのように定義されています。アプリ全体を通じて

const dataIdFromObject = o => { 
    if (o.__typename != null && o.id != null) { 
    return `${o.__typename}-${o.id}` 
    } 
    return null 
} 

、私はcurrentShopの異なるフィールドを求めてクエリを実行しています。様々な点で、currentShopを変化させる突然変異も存在し、その突然変異は常にShop型の結果を返している。しかし、currentShopには関係がないので、Apolloはルートクエリキャッシュポインタの更新方法を知ることができません。

問題を表すデモをCodeSandboxにしました。バックエンドはApollo LaunchPadで作成されています。別のブランチを選び、数秒待つ(最適化を気にしなかった)、それは動作する。

ShopSelectButtonコンポーネントで「魔法」が発生しています。 refetchQueries行をコメントアウトすると、状況が壊れてしまいます。店舗はサーバー上で正しく選択されています(リロード後に表示されます)が、クライアントは死んだ動物のように機能します。

私の問題はrefetchQueriesであり、コードがあまりにも強く結合してしまいます。私は、他のコンポーネントとそのニーズについて知るために、アプリケーションの一部にコンポーネントを持たせたくありません。また、正直言って、リペッチとは、キャッシュ全体に行き渡ることを意味し、ほとんどの場合、バックエンドからは常に読み込みません。

私はこれに対する他のアプローチが何であるか疑問に思っています。スキーマをよりステートレスに構築し、代わりにフロントエンドアプリで状態を維持する必要がありますか?

答えて

1

突然変異は、クエリを再フェッチせずに動作するはずだと思います。あなたは、突然変異の結果本体の関連するクエリから必要なデータをすべて追加するだけです。

chromeのapolloクライアント開発ツール拡張機能をインストールしようとしましたか?そこでは、異なるクエリのcurrentShop要素がtypenameとidを介してShop型に関連しているかどうかを簡単に確認できます。 この場合、アポロは突然変異の後に更新されるはずです。

変異結果が正しく更新されるために必要なすべてのデータを取得するには、アプリケーションにフラグメント構造を追加することをお勧めします。店舗からのデータを必要とするすべてのコンポーネントに、要件を定義するフラグメントフィールドがあることを意味します。 断片を集めて突然変異体に加える。もちろんこれを行うと、他のコンポーネントと突然変異の間で同じ結合があります。

もう1つの選択肢は、Shopタイプのすべての可能なデータを突然変異の結果に追加することです。

+0

確かに私はタイトなカップリングが嫌いです。特に、私のアプリがどのモジュールがあるのか​​わからないほどモジュラー化する必要があるのならば。 – FredyC

+0

また、あなたが記述している関係はそこにあるとは思わない。 'currentShop'は特定のtypename:idを指していて、突然これはサーバ上でのみ変更されます。アポロはそれを知る方法がありません。私は 'writeQuery'を使って本質的に動作するこのポインタを更新しようとしましたが、それらのすべてのクエリのための他のすべてのフィールドがまだありません。 – FredyC

+0

とにかく、私は、ステートレスサーバーがおそらくより良いアプローチであることに気付きました。これはその試みの結果です。 https://codesandbox.io/s/ly9j7w1l9 – FredyC

関連する問題