-
-
Notifications
You must be signed in to change notification settings - Fork 457
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
Clarify expected behavior of fetching and stale #2282
Comments
Yep, that's totally expected behaviour, but with the added difficulty that without knowing how you configured the query, what request policy you're using, how you've set up Graphcache, and whether you're using schema awareness, the exact explanation will differ slightly 😅 The general explanation that always applies is pretty simple. There's a varying level of operations going on, of which there are two. These are also associated with varying levels of certainty. The first important thing to note is that it may be interesting to note that This is compared to In other words, as long as your local query, in a component, is waiting for a result, it will indicate that it's doing so via In the UI state we may actually be waiting for a different result (maybe because the query and/or variables changed) which means that However, This is important because in Graphcache there are many mechanisms that can cause a result to update in the background, which often triggers network requests. With both flags there's some "magic" going on behind the scenes that increases their certainty. In this sense, we're basically anticipating GraphQL becoming more equipped to deal with partial and stale states itself. Nullability operators can help us here for instance: #2018 On the other hand, we're also taking React Suspense and Relay as a future inspiration. We don't see "staleness" as a topic that's completely finished for us. Rather, we can see component-level fragments and utilities helping us to say what's required, can be stale, or should never be stale on a component-level. We completely understand that this may sound more compelling for React users than other frameworks, but our greater ambition here is to eventually find time to implement Relay-style composition patterns, which eventually mean that we'll make "harder recommendations" and patterns around this. But for now what this means is: in some cases you'll have to be aware that To close this off, there are many examples and comparisons to this. Of course, all our bindings attempt to store their previous state while they're This obviously is a more pressing issue when you talk about Nested data is also a space where the Hope that makes this a little clearer ✌️ |
You guys are awesome. Thanks for taking the time to detail this. I think some of this could be great in the documentation. Some clarifying questions:
Do you mind elaborating on what you define as a flag/local state? I'm not quite following the difference here. As a naive consumer,
In my example above,
In my example above with the second todo, it was a different result. Should i have expected
I imagine an example is something like Again, thanks for taking the time. Much appreciated! |
Yea, no worries! Let me explain it conceptually, and then link some code examples. It can probably be seen clearest in the Vue bindings:
Meanwhile,
Usually, that's not a problem. I'm obviously not sure what your UI looks like, but I suspect you'd be displaying both pieces side-by-side. So, if you get
Precisely! When information "goes missing" it's pretty likely that Graphcache will trigger more requests, either for the "current" query that it receives or other ones (i.e. when something is invalidated and hence re-queried from the cache) |
Feel free to close if you'd like. I think the main outcome i'd love to see is some docs improvements. I'm still trying to wrap my head around everything you've said. Thanks so much! |
I think I'm dealing with this same issue and I'm quite at a loss. I have:
I can walk through this process, navigate back to screen 1, and keep doing it over, and these two screens behave precisely the same every time, making me suspect this is by design. I've figured out that I can use I'm not blocked so I'm not asking anyone to debug, just curious if this behavior is expected and would love to understand why. cc/ @kitten since you had such a firm grasp in earlier comments |
@kitten @JoviDeCroock What will be the recommended way of re-executing background queries without marking existing results as stale? My use case is custom refocus exchange, it compares refetched data with existing and only updates if it was actually changed. This way it will only re-render if response did change. If existing data is equal to response data - it returns existing result and also sets response.data to cached one, so other exchanges will receive same object reference. Main issue is that |
This is kinda off-topic but why would a re-render be bad? It is the guarantee in React |
Well, from a view perspective there is nothing to update, and also there could be heavy queries to render, that actually didn't change but it will be re-rendered on focus. Will be happy to open another issue/discussion if this is off-topic, if needed. If this Upd: Ended up with a dedicated client (without cache exchange) for doing background fetches and propagating only changed results back to main client results stream, which is probably the way how it should be done. But being able to re-execute query without marking results as stale would simplify this a lot. |
In my case I have a problem where I'm still looking for other threads which is more relevant to my issue, but this is the first google result I found. with However, with Self note -> https://jsramblings.com/how-to-check-if-your-component-rerendered-and-why/ |
@ceefour That's really odd. Mind opening a new discussion thread for that? This usually happens in one of two cases:
|
Update: @kitten regarding my issue before #2282 (comment) It was caused by After I replaced It's definitely not relevant to this issue, but https://formidable.com/open-source/urql/docs/api/urql/#usequery doc should have BIG warning on I almost fell back to using |
@ceefour I think you just have to memoize the context. |
I cannot see how it's possible to display a loading indicator in a reasonable way currently, what am I missing?
The closest I can see currently is checking if either fetching or stale is true - but we'll get a false positive if we just have an outdated cache (I'm working with an offline-enabled app currently - so that would be expected to happen). Am I missing something here? |
+1 This seems unusable at the moment. I tried upgrading from URQL In This doesn't seem to be the case in |
I believe #3079 (and #2962) in upcoming versions will help with this. We've struggled to write documentation that is instructive and in the rigth order, and hence, sometimes the documentation skips over some behavioural details or some minor API details. We belive that TSDocs can solve this much more extensively, and we'll be replacing our API docs with them. The reason is that TSDocs have the ability to show up in all editors with a TypeScript LSP integration, something that VSCode comes with natively, and something many TypeScript developers set up for a good experience. This allows us to communicate small or big API functionality where it matters. Specifically, |
Hi! 👋
This is more of a request than a bug report, but perhaps it's a bug?
I'm a new user of urql. I'm evaluating the library coming from a fair bit of exp. with react-query and graphql-codegen. One of the issues i ran into was the behavior of
fetching
andstale
.I have a query that looks something like the contrived example below:
Where
commonStuffs
is the same result no matter whichtodo
is being queried. Now where i stumbled was the following:todos/1
which runs above query withid = 1
.fetching = true
andstale = true
todos/2
which runs above query withid = 2
.fetching = false
andstale = true
In the second todo query, part of the query was already available in the cache and thus we got "partial results" (i think that's how you refer to them?). I was a bit tripped up by the nomenclature of the two states and it felt awkward.
For example i might have some conditional logic like so:
I changed it to the following to avoid a flash of "not found" before the second query finished, but it felt quite awkward:
One of the nice things about react-query was the type discrimination when checking
isLoading
. When you had a check that guaranteed thatisLoading = true
in my above example, then you knewdata
would be defined, even ifdata.todo
was null.I'm not sure what the outcome of this issue should be. IMO the second query should have said it was fetching - because IMO it is fetching data? Perhaps we need some documentation around these states, and suggestions for how to deal with fetching/stale states, best practices, etc.
urql version & exchanges:
urql@2.1.3
@urql/exchange-graphcache@4.3.6
The text was updated successfully, but these errors were encountered: