Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
christophediprima opened this issue Oct 20, 2020 · 10 comments
Labels
🏓 awaiting-team-response requires input from the apollo team 🛎 subscriptions

Comments

@christophediprima
Copy link

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.

@christophediprima
Copy link
Author

christophediprima commented 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.

@mzbyszynski
Copy link

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?

@christophediprima
Copy link
Author

@mzbyszynski do you have something new about this?

@devaublanc
Copy link

devaublanc commented Jun 29, 2021

@christophediprima Same issue here

@Avi-Cohen-Nehemia
Copy link

Hey 👋🏼
I'm dealing with the same issue right now, is this going to be fixed? I see there is an open PR for this from July last year

@ECCKaka
Copy link

ECCKaka commented Jun 1, 2022

Hi,
I am facing the same issue.

  const { newPostData, newPostLoading, newPostError } = useSubscription(  
	NEW_POST,
	{
		onSubscriptionData: (data) => {
			console.log("onSubscriptionData", data);
		},
	}   
  );

the newPostData, newPostLoading, newPostError are always undefined, but inside the onSubscriptionData, it actually has the data I wanted.

@bignimbus bignimbus added 🏓 awaiting-team-response requires input from the apollo team 🛎 subscriptions labels Nov 10, 2022
@Amir-Pasha-Bagheri
Copy link

Hi, I am facing the same issue.

  const { newPostData, newPostLoading, newPostError } = useSubscription(  
	NEW_POST,
	{
		onSubscriptionData: (data) => {
			console.log("onSubscriptionData", data);
		},
	}   
  );

the newPostData, newPostLoading, newPostError are always undefined, but inside the onSubscriptionData, it actually has the data I wanted.

You have forgotten to write data , loading and error behind them , it should be like

const { data : newPostData, loading : newPostLoading, error : newPostError } = useSubscription

@phryneas
Copy link
Member

phryneas commented Aug 1, 2024

We recently released a rewrite of useSubscription in Version 3.11.

Data is now synchronized using useSyncExternalStore, just like in useQuery - and I believe the bug you were surfacing here should not happen anymore.

If you find any problems with useSubscription after 3.11, please open a new issue. I'm closing this issue since the code that originally caused this issue is not part of the library anymore.

@phryneas phryneas closed this as completed Aug 1, 2024
Copy link
Contributor

github-actions bot commented Aug 1, 2024

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.

Copy link
Contributor

github-actions bot commented Sep 1, 2024

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
For general questions, we recommend using StackOverflow or our discord server.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🏓 awaiting-team-response requires input from the apollo team 🛎 subscriptions
Projects
None yet
Development

No branches or pull requests

8 participants