react-apollo
react-apollo copied to clipboard
Subscription component loading forever
Intended outcome:
Get data from subscription using Subscription component from @apollo/react-components.
Result data should be updated, including loading value.
<Subscription subscription={SUBSCRIPTION} client={client}> {this.myFunction} </Subscription>
Client is created using this:
export const createClient = ({ uri, ws }) => new ApolloClient({ defaultOptions: { watchQuery: { fetchPolicy: 'cache-and-network', }, }, cache, link: ApolloLink.from([ ApolloLogger, onError(({ graphQLErrors, networkError }) => { if (graphQLErrors) { graphQLErrors.map(({ message, locations, path }) => console.log([GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path} ) ); } if (networkError) { console.log([Network error]: ${networkError}`);
}
}),
new RetryLink({ attempts: { max: Infinity } }).split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
new WebSocketLink({
uri: ws,
options: {
reconnect: true,
},
}),
new HttpLink({
uri,
credentials: 'same-origin',
})
),
]),
typeDefs,
resolvers,
});
` Actual outcome:
Result data does not get updated, even when apollo-link-logger shows the result in the console.
Simple console.log(result) is being used in myFunction to see the callback results. First time it's rendered it logs with loading=true. It never gets called again with loading=false or any other data (no console.log printed).
How to reproduce the issue:
Normally this will happen with subscriptions. Every now and then it works as expected, but most of the time it just does not work.
Version
System: OS: macOS 10.14.6 Binaries: Node: 10.16.2 - ~/.nvm/versions/node/v10.16.2/bin/node Yarn: 1.17.3 - /usr/local/bin/yarn npm: 6.9.0 - ~/.nvm/versions/node/v10.16.2/bin/npm Browsers: Chrome: 76.0.3809.100 Safari: 12.1.2 npmPackages: apollo-cache-inmemory: ^1.6.3 => 1.6.3 apollo-cache-persist: ^0.1.1 => 0.1.1 apollo-client: ^2.6.4 => 2.6.4 apollo-link: ^1.2.12 => 1.2.12 apollo-link-error: ^1.1.11 => 1.1.11 apollo-link-http: ^1.5.15 => 1.5.15 apollo-link-logger: ^1.2.3 => 1.2.3 apollo-link-rest: ^0.7.3 => 0.7.3 apollo-link-retry: ^2.2.14 => 2.2.14 apollo-link-ws: ^1.0.18 => 1.0.18 apollo-utilities: ^1.3.2 => 1.3.2
Any chance you can provide a small runnable reproduction that shows this happening?
I was facing this as well. The WS was still receiving all messages just fine, but for some reason the values within the useSubscription hook got staled. My guess is when the server responds too fast (under the 100ms ish) it could make this to happen.
The workaround I did relies on the onSubscriptionData, like below
const [values, setValues] = useState<
Partial<SubscriptionResult<SubscribeActivePromotion>>
>({});
useSubscription<SubscribeActivePromotion, SubscribeActivePromotionVariables>(
subscribeActivePromotion,
{
onSubscriptionData(options) {
setValues(() => options.subscriptionData);
},
variables: {
partnerId: props.partnerId,
},
}
);
Having the same problem. The workaround @schettino suggested is working for me! :)
@hwillson not able to provide a runnable right now since I'm using react native. If it guides you better, it's very likely to reproduce when debug is enabled and dev tools hooked.
I have the same issue. Workaround from @schettino works great with one small addition - don't forget to pass { loading: true } when initializing state.
const useSubscription = <TData, TVariables>(
query: DocumentNode,
options?: SubscriptionHookOptions<TData, TVariables>,
) => (variables: TVariables) => {
const [values, setValues] = useState<Partial<SubscriptionResult<TData>>>({
loading: true
});
__useSubscription<TData, TVariables>(
query,
{
...options,
variables,
onSubscriptionData: (options) => {
setValues(() => options.subscriptionData);
}
}
);
return values;
};
I have the same issue, subscription keeps loading at first initialize, reload the app it's work without issue. I try to set lazy in subscription options to true and it's work on my case.
Probably related: https://github.com/apollographql/react-apollo/issues/3802
Root cause: As identified in the video, I believe the root cause is a race condition in
/packages/hooks/src/data/SubscriptionData.tswhich implicitly requires thatisMountedwill be set totruebeforeupdateResultis called, and this is not always the case.