Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Child component stuck in loading state, but the data is already loaded. #2899

Closed
OurMajesty opened this issue Mar 25, 2019 · 42 comments
Closed
Assignees

Comments

@OurMajesty
Copy link

OurMajesty commented Mar 25, 2019

Intended outcome:

There are two React components:
parent: Requests (stateful component)
child: graphql(List), having prop state

There's buttons in Requests, which are setting state.
In turn, List component's query variable is set by state prop, which is equals to state in Requests component.
So the data for List should be refetched every time I click button in Requests.

Actual outcome:

Data is refetched successfully, but sometimes (80% of times) List is stuck in loading state. If I click some other button again, loading is resolving, the data is new.

I did try install react-apollo 2.4.1 and it fixed the error.
Also, if I recreate component every time (key prop) it helps too.
BTW, [email protected] was having the same issue

How to reproduce the issue:

I did create code example using local state, but it works fine, so I suggest the problem reproduction is requiring real graphql endpoint.
Real GraphQL endpoint example is failing as expected:
https://codesandbox.io/s/039pyz78pn

Version

@bogdansoare
Copy link

also having this issue

@hwillson
Copy link
Member

@OurMajesty Any chance you could try building a reproduction using https://github.com/apollographql/react-apollo-error-template? It will simulate having a backend, so hopefully that will help.

@OurMajesty
Copy link
Author

@hwillson Yes, I did try it right away, but it worked fine. Furthermore, I have found additional places in my app, where it stucks too. For example, dynamic search, that's why I mentioned this issue in #2808.
I wish Launchpad still worked, it would help to reproduce.
Had a lot of work lately, but still planning to find a way. Maybe use some open GraphQL API.

@OurMajesty
Copy link
Author

OurMajesty commented Mar 27, 2019

If someone needs a workaround, right now I am using react-apollo 2.4.1 along with client 2.5.1 and other latest libraries and doesn't really found any compatibility issues, local state and client queries work fine too.

@OurMajesty
Copy link
Author

@hwillson I did finally reproduced it. The same Codepen link: https://codesandbox.io/s/039pyz78pn

First, click on "computer". Result: empty list.
Second, click on "noop". Result: empty list again.
And it stuck.

@Cheesier
Copy link

Cheesier commented Apr 3, 2019

Having this exact same issue, seems to me that the issue is when variables change but the response remains the same.

@OurMajesty
Copy link
Author

I сonfirm this, updated the reproduction, added another button, which returns not empty data, but the same as "SDK" button, and it is stuck too, if you click them one after another.

@Experiment8
Copy link

Experiment8 commented Apr 16, 2019

Hello there,

I have the exact same issue, when the response is the same, no matter if the filters change, the loading state doesn't change and the component is stuck in a loading state.
If the list changes content there's no problem at all.

[email protected]
[email protected]

@pfarnach
Copy link

Also experiencing this in [email protected] and [email protected]. I have a select component updating a variable that's passed into my query. One of the selected values, when passed in as a variable to the query, produces an error and the other returns data. This is expected behavior in my case. But after switching back and forth twice, the query that was originally returning an error gets stuck in the loading phase.

@ElForastero
Copy link

Same issue.

"apollo-cache-inmemory": "^1.5.1",
"apollo-client": "^2.5.1",
"apollo-link": "^1.2.11",
"apollo-link-error": "^1.1.10",
"apollo-link-http": "^1.5.14",
"apollo-link-state": "^0.4.2"

@ElForastero
Copy link

Got the same error with client.queryManager.refetchQueryByName()

@brandhaug
Copy link

I'm experiencing the same problem when the data returned from the previous query is the same as the latest query.

@palianah
Copy link

palianah commented May 2, 2019

I am having the exact same Problem, loading State is not updating. Have Version 2.5.4.
Would be great if this Issue will be fixed in the next Version/s.

@felixsusanto
Copy link

Any update on this, I'm also experiencing this issue.

@honestbonsai
Copy link

Had this issue with "apollo-boost": "^0.3.1" , Query was always stuck on loading. This is with a pollInterval={1000}

My work around was

const shouldShowLoading = loading && !data.myData;
if (shouldShowLoading) {
  return <Loading />;
}

// use data.myData if it exists
doSomething(data.myData)

loading will be false until the data changes in the db. Otherwise, loading is always true with the same query params. However, data is still returned from the query, so I just used that instead.

@DanielYosilevich
Copy link

"apollo-boost": "^0.3.1",
"graphql": "^14.2.1",
"react": "^16.8.6",
"react-apollo": "^2.5.4"
using 2 seconds polling

This is a clear bug and in my application it happens absolutely randomly. Drove me nuts. Have only one template query and a bunch of client queries/mutations. Wide use of react hooks/custom hooks.
Kudos to honestbonsai for brilliant work around!

@yuya-fujimoto
Copy link

yuya-fujimoto commented May 19, 2019

I did some digging on this issue and the situation addressed here happens when falling into this condition. (https://github.com/apollographql/react-apollo/blob/master/src/Query.tsx#L335-L340)

This exists as mentioned in the comments (https://github.com/apollographql/react-apollo/blob/master/src/Query.tsx#L303-L309)

When the Query component receives new props, or when we explicitly
re-subscribe to a query using resubscribeToQuery, we start a new
subscription in this method. To avoid un-necessary re-renders when
receiving new props or re-subscribing, we track the full last
observable result so it can be compared against incoming new data.
We only trigger a re-render if the incoming result is different than
the stored lastResult.

I might be wrong but while above is a valid approach, maybe there is an assumption that this.queryObservable's next is going to be fired at least twice(when loading: true & loading: false)? But as I was investigating, loading is true only when this.querySubscription is newly assigned, i.e. when Query component is mounted.
In other cases such as changing query variables, next is fired only when the new data arrived and loading is false, which means even when query variables changed if the query result is shallowly equal by chance(such as empty array), Query component doesn't call forceUpdate and loading remains true in the child components.

In @OurMajesty 's reproduction link, if you press "computer" and "noop" back and forth, loading stays true since both cases the query result is an empty array.

https://codesandbox.io/s/039pyz78pn

@mhuconcern
Copy link

mhuconcern commented May 28, 2019

Also experiencing this issue. On "apollo-client": "^2.6.0","react-apollo": "^2.5.6".
We only trigger a re-render if the incoming result is different than the stored lastResult. Is it possible to make this a option we can override, i.e force re-renders or atleast it should not be stuck in loading? Or integrate the boolean workaround by @honestbonsai into loading

@duenguyen2103
Copy link

I skip/comment the loading condition and it works.
Also I try the workaround by @OurMajesty using react-apollo 2.4.1 and it works too.

@OurMajesty
Copy link
Author

I have no skip in the reproduction. There's probably another different error, when skip is helpful: #2808

@Cheesier
Copy link

Cheesier commented Jun 3, 2019

@hwillson some attention on this issue?

@LucaProvencal
Copy link

Also having this issue.

@jasonpaulos
Copy link
Contributor

Hi everyone! Thanks for catching this bug, and thank you @OurMajesty for providing a great reproduction. I will continue to investigate the source of this bug, but in the meantime I may have found another workaround.

In my tests on the reproduction, it appears that this issue only happens when the query's fetchPolicy is "network-only". Changing the fetchPolicy to something else, such as "no-cache" results in proper loading of the query (more info on fetchPolicy: https://www.apollographql.com/docs/react/api/react-apollo/#optionsfetchpolicy). I'm curious to see if this change works for the rest of you who are also reporting the issue. Please let me know!

@OurMajesty
Copy link
Author

Commenting out fetchPolicy: "network-only" is helping in the reproduction - loading is never stuck.
fetchPolicy: "cache-only" helps too, and saves "network-only" behavior (request made every time)
But I have two issues with such workaround:

  • there's cases, when I still need to get some data from the cache, which contains latest fetched data (example: isInCart resolver for product, which uses some cart data from the cache, but the cart itself is network-only)
  • when using "cache-only" fetchPolicy first render is neither loading or error, but there's no data, second render is having the data:
    изображение

@LucaProvencal
Copy link

no-cache seems to be helping. Will have to test more and confirm

@jasonpaulos jasonpaulos self-assigned this Jun 12, 2019
hwillson pushed a commit that referenced this issue Jun 21, 2019
…3126)

* Add ability for Query to detect when lastResult is not accurate

* Add regression test for #2899

* Streamline interactions with Apollo Client

This commit streamlines some of the React Apollo <--> Apollo Client
communication points, to help reduce temporary placeholders
and variables used by React Apollo to control rendering. The
current data result that is to be rendered now comes from only one
place, the initialized `ObservableQuery` instance.

* Code review tweaks

* Changelog update
@jasonpaulos
Copy link
Contributor

A fix for this issue has been merged! Thanks to everyone who helped report and debug this issue

@TroyWolf
Copy link

TroyWolf commented Jul 7, 2019

This thread appeared to be the same issue I'm having except I have now updated to apollo-client 2.6.3 and still have a loading indicator that occasionally stays true despite the query returning from my API quickly and successfully.

I believe I have found the pattern that is the difference. The issue appears to be caused by having more than one <Query> polling at the same time. I have a parent component using <Query> to poll every 10 seconds for fresh data.

    <Query query={query} variables={{ id: 1234 }}>
      {({ loading, error, data, startPolling }) => {
        if (error) {
          return <div>Error!</div>;
        }

        if (!loading) {
          startPolling(5000);
        }      

There is a child component with a 2nd <Query> also doing 10s polling for a different set of data.

When both requests kick off at the same time (or very close), the loading problem occurs.

To be clear, the API requests are coming back fast and successful. They are, in fact, not loading despite the fact loading=true is returned by <Query>.

If I turn off polling on my parent component (<Query> #1), the loading indicator issue goes away in the child component (<Query> #2).

@jasonpaulos
Copy link
Contributor

Hi @TroyWolf, thanks for reporting that issue! I've moved it to a new thread, #3226, because I think it's slightly different than the original issue here.

@developdeez
Copy link

A fix for this issue has been merged! Thanks to everyone who helped report and debug this issue

What's the fix? I'm using "apollo-client": "^2.6.2" And noticed this in my HOC when I refresh the page.
The HOC checks if user is logged in but uses cache-first for speed.

@jasonpaulos
Copy link
Contributor

@developdeez The fix was to the internals of how react-apollo keep track of query results, which was merged in #3126. If you use the latest version of react-apollo 2 or 3, this exact problem shouldn't happen anymore. Note that this issue was pretty much exclusively about the network-only fetch policy, so if you're seeing an issue with cache-first I recommend that you create a separate issue. Thanks.

@arianofaoms
Copy link

arianofaoms commented Sep 4, 2019

+1 I have the same problem using react apollo 3

@AlexDunmow
Copy link

This problem is definitely not fixed.

@hwillson
Copy link
Member

hwillson commented Sep 8, 2019

If anyone here can provide an updated repro that uses React Apollo 3.1.0, we'll take a look. Thanks!

@TSMMark
Copy link
Contributor

TSMMark commented Sep 10, 2019

I'm on 3.1.0 and still loading forever unless using no-cache fetch policy. We are still using Query HOCs, not even hooks yet. I could try to get a minimal repro — is there a repo I should fork to try to get a repro?

@OurMajesty
Copy link
Author

I did update my old repro to latest react-apollo and everything works fine:
https://codesandbox.io/s/039pyz78pn

@TSMMark
Copy link
Contributor

TSMMark commented Sep 10, 2019

@OurMajesty yeah it seems to work fine in your updated sandbox. Congrats!

I'm trying to reduce my production code to a minimal example. Are there any good debugging tools for debugging or logging, such as dumping the apollo cache or logging when a query is staying loading too long?

@OurMajesty
Copy link
Author

I would suggest Apollo Dev Tools and also apollo-link-logger

@jurajkrivda
Copy link

In React Native app:

"react-apollo": "^3.1.0-beta.0",
"@apollo/react-hooks": "^3.1.0-beta.0",

same problem. :-(

@TSMMark
Copy link
Contributor

TSMMark commented Sep 17, 2019

Anyone know if this is perhaps fixed in 3.1.1? NPM says was released 2 days ago

@dylantf
Copy link

dylantf commented Sep 24, 2019

Anyone know if this is perhaps fixed in 3.1.1? NPM says was released 2 days ago

I just updated from 3.0.1 to 3.1.1 after seeing your comment and it fixed it for me. Mine was getting stuck loading after getting a 500 from the server using the useQuery hook.

@lukebettridge
Copy link

lukebettridge commented Jan 1, 2020

Using 3.1.3 but still having the same issue using the Query element (when the same data is returned), setting the fetchPolicy prop to "cache-only" seems to fix it for now.

@kaatt
Copy link

kaatt commented Jan 2, 2020

Also experiencing this and waiting for a fix.

@hwillson @jbaxleyiii @helfer @jasonpaulos Can you please reopen this issue? Someone opened a new issue: #3774
Would appreciate it if you can take a look at it since this bug has been present since a rather long time.

@ajhool @nmklotas If you can create a minimal repo that reproduces the issue, it'll really help the maintainers in fixing this

Related: #3488 #3361 #3425

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests