-
-
Notifications
You must be signed in to change notification settings - Fork 641
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
fix(query): create QueryObserver with initial options #1417
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit b422598:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our implementation is pretty complicated. (I hope to re-design for better maintainability.)
Having a test is very nice. Please try keeping observerAtom
.
src/query/atomWithQuery.ts
Outdated
const observerAtom = atom((get) => { | ||
const queryClient = getQueryClient(get) | ||
const defaultedOptions = queryClient.defaultQueryOptions< | ||
let observer: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't define a variable here (as it can be global).
Can we have another solution?
One hacky solution is to use WeakMap<QueryClient, QueryObserver>
, if we don't find any other methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second look, I think we can probably just have this in observerAtom
.
const options =
typeof createQuery === 'function' ? createQuery(get) : createQuery
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I tried this, but this test failed query no-loading with keepPreviousData
const options = typeof createQuery === 'function' ? createQuery(get) : createQuery
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, no.. Maybe that was the reason.
I'm still not sure if I understand the problem. So, we need to specify queryKey
when we first create an observer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For all tests to pass, the observer can only be created once per query.
If createQuery is a function, and it's used in observerAtom, then a new observer would be created if createQuery has a dependency that changes.
I'm new to Jotai, so I don't know how we could have it read the options, without tracking its dependencies, so that only one observer is created.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
once per query
Does it mean if the queryKey
is the same? regardless of the other parts of the query.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, we need to specify
queryKey
when we first create an observer?
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the problem is that the current atomWithQuery
allows changing queryKey dynamically.
We probably shouldn't allow it.
That is going to be a breaking change in its API. If we were to add such a change, we have also other things to change.
Please let us know if you find any solution with dynamic queryKey, then we can merge it meanwhile.
fa10081 tried to use only |
Would it work if |
but, then it doesn't work if |
It would ensure the observer isn't recreated when the query key changes. The new query key would be set regardless in the queryAtom, when |
Oh, so
Can you try this then? If it works, we'll think about some refactors. (basically, we don't use |
I've implemented something similar to I removed the use of |
Nice. Please note that Now, if our requirement is not to re-create observer unless queryClient changes, then probably WeakMap cache is a better option than
Oh, this is great. Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After working on this, I noticed the problem is not about caching observer across options, but just keeping previous data should make more sense.
I'm not 100% confident and happy with the current implementation, but it's simpler and closer to jotai/urql
and would be a good path for future refactoring.
There's a little behavioral change, which is more or less a fix in this context.
Thanks for your investigation and work! Without them, this wouldn't have happened.
// FIXME why does this fail? | ||
// unsubscribe = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't be able to solve this. Maybe I'm missing something. Happy if someone tries it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, maybe it's Strict Effect's double invocation.
Related Issues
Fixes #1416
Summary
options
.keepPreviousData
.jotai/urql
impl.write
function no longer returns a promise.Check List
yarn run prettier
for formatting code and docs