I was wondering if there's an elegant way to trigger the refetch of a query in react-apollo when a subscription receives new data (The data is not important here and will be the same as previous one). I just use subscription here as a notification trigger that tells Query to refetch.
I tried both using Subscription component and subscribeToMore to call "refetch" method in Query's child component but both methods cause infinite re-fetches.
NOTE: I'm using react-apollo v2.1.3 and apollo-client v2.3.5
here's the simplified version of code
<Query
query={GET_QUERY}
variables={{ blah: 'test' }}
>
{({ data, refetch }) => (
<CustomComponent data={data} />
//put subscription here? It'll cause infinite re-rendering/refetch loop
)}
<Query>
It's possible if you use
componentDidMount
andcomponentDidUpdate
in the component rendered by the Subscription render props function.The example uses
recompose
higher order components to avoid too much boilerplating. Would look something like:Another way of accomplishing this while totally separating Query and Subscription components, avoiding loops on re-rendering is using Apollo Automatic Cache updates:
Note:
compose
andlifecycle
are recompose methods that enable easier a cleaner higher order composition.Finally I figured it out myself with the inspiration from Pedro's answer.
Thoughts: the problem I'm facing is that I want to call Query's refetch method in Subscription, however, both Query and Subscription components can only be accessed in render method. That is the root cause of infinite refetch/re-rendering. To solve the problem, we need to move the subscription logic out of render method and put it somewhere in a lifecycle method (i.e. componentDidMount) where it won't be called again after a refetch is triggered. Then I decided to use graphql hoc instead of Query component so that I can inject props like refetch, subscribeToMore at the top level of my component, which makes them accessible from any life cycle methods.
Code sample (simplified version):