question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

useSubscription "loading" and "data" out of sync when used with other hooks

See original GitHub issue

I am using version 3.2.4 of @apollo/client and there is no way of using a useEffect to check when loading moves from true to false with new data when you have other hooks changing state. You simply get loading back to false and the old data as soon as you are using other hooks that changes the state of your component.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:6
  • Comments:7

github_iconTop GitHub Comments

9reactions
mzbyszynskicommented, Nov 25, 2020

We are running into this same bug. As far as I can tell this problem is caused because the useSubscription hook stores the most recent data returned by the subscription in state, but it doesn’t store or update that state when the variables change. In that case a render is triggered and the hook returns { loading: true, data: undefined }, but still has the previous data in state. If another render is triggered after that by anything other than data being returned from the subscription, then the old data useSubscription still has in state will be returned.

I think the right way to fix this would be for useSubscription to also store the loading: true state change in state, or at least update the data stored in state to undefined when loading starts, so that after a variable change the hook would return data: undefined until some new data actually came through the subscription.

I tried making this change to useSubscription.ts but it broke a lot of unit tests so I’m not super confident about it. In any event it would be a bigger than 20 line change so I think even if it is the correct fix, it would qualify as a Big PR.

Would love to get some feedback from someone more familiar with the useSubscription and the SubscriptionData class. Maybe @hwillson?

1reaction
christophediprimacommented, Oct 22, 2020

We finally found a work around for this issue.

We don’t use the returned values of the useSubscription hook anymore but manually maintain a state containing loading and data. We have a usEffect hook, that sets the loading state to true when subscription variable changes and we set it back to false with the new data in the onSubscriptionData that way we can be sure that when loading moves from true to false we have the new data with it.

const [subscriptionState, setSubscriptionState] = React.useState({
    data: undefined,
    loading: true,
});
  
const prevSubscriptionVariables = usePrevious(subscriptionVariables);

useEffect(() => {
   if (!equals(subscriptionVariables, prevSubscriptionVariables)) {
      setSubscriptionState({
         data: undefined,
         loading: true,
      });
   }
},
[subscriptionVariable, prevSubscriptionVariable]);

 useSubscription(CAPTURE_AGGREGATE_SUBSCRIPTION, {
    onSubscriptionData: ({subscriptionData}) => {
      setSubscriptionState({
        data: subscriptionData.data,
        loading: false,
      });
    },
    variables: subscriptionVariables,
  });

const previousSubscriptionState = usePrevious(subscriptionState)
useEffect(() => {
   if(previousSubscriptionState.loading && !subscriptionState.loading){
      console.log("Here is your new data after changing variable", subscriptionState.data)
   }
}, [subscriptionState, previousSubscriptionState]);

Hope this will help someone and that this will be fixed soon in the useSubscription hook. I had a look the hook trying to figure out why it was happening but couldn’t find a solution.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Apollo client useSubscription hook is loading forever. How do ...
But my useSubscription hook has the status of loading=true forever, and no data is being displayed. I am not sure where to start ......
Read more >
GraphQL subscriptions with Apollo Client React Hooks and ...
Again, I'm using a functional React component and a couple of different React hooks. The first hook is useSubscription on line 7.
Read more >
Use GraphQL Subscriptions in a React App - Pluralsight
Instead of using the useQuery hook, you used the useSubscription hook. The hook still returns loading , data , and error in the ......
Read more >
Need to use setstate() of data received from GraphQL ...
setState({ fishes: data }); }. And Change const haveAnyFish = () => ( <Subscription subscription={gql`${SUBSCRIPTION_SYNC}`} > {({ loading, ...
Read more >
RTK Query Overview - Redux Toolkit
It is designed to simplify common cases for loading data in a web ... like Redux to cache data, the use cases are...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found