From 87ea4eca9a2408c9573283202a54a5832fcf82c2 Mon Sep 17 00:00:00 2001 From: Alexander Johansson Date: Fri, 13 Dec 2024 12:03:29 +0100 Subject: [PATCH] wip --- packages/query-core/src/queryObserver.ts | 13 ++++- .../src/__tests__/useQuery.promise.test.tsx | 21 ++++++-- packages/react-query/src/__tests__/utils.tsx | 13 +++++ packages/react-query/src/useBaseQuery.ts | 53 ++++++++++++------- packages/react-query/vite.config.ts | 1 - 5 files changed, 74 insertions(+), 27 deletions(-) diff --git a/packages/query-core/src/queryObserver.ts b/packages/query-core/src/queryObserver.ts index 3dc751f5cd..27ec8c5d34 100644 --- a/packages/query-core/src/queryObserver.ts +++ b/packages/query-core/src/queryObserver.ts @@ -649,6 +649,7 @@ export class QueryObserver< } updateResult(notifyOptions?: NotifyOptions): void { + const prevResult = this.#currentResult as | QueryObserverResult | undefined @@ -700,9 +701,18 @@ export class QueryObserver< return Object.keys(this.#currentResult).some((key) => { const typedKey = key as keyof QueryObserverResult + if (!includedProps.has(typedKey)) { + return false + } const changed = this.#currentResult[typedKey] !== prevResult[typedKey] - return changed && includedProps.has(typedKey) + console.log('changed', { + key, + changed, + includedProps, + }) + + return changed; }) } @@ -716,6 +726,7 @@ export class QueryObserver< #updateQuery(): void { const query = this.#client.getQueryCache().build(this.#client, this.options) + console.log('updating query') if (query === this.#currentQuery) { return } diff --git a/packages/react-query/src/__tests__/useQuery.promise.test.tsx b/packages/react-query/src/__tests__/useQuery.promise.test.tsx index ec07d2d2b2..5efc62473a 100644 --- a/packages/react-query/src/__tests__/useQuery.promise.test.tsx +++ b/packages/react-query/src/__tests__/useQuery.promise.test.tsx @@ -12,7 +12,9 @@ import { useQuery, } from '..' import { QueryCache } from '../index' -import { createQueryClient, queryKey, sleep } from './utils' +import { createDeferred, createQueryClient, queryKey, sleep } from './utils' + + describe('useQuery().promise', () => { const queryCache = new QueryCache() @@ -75,11 +77,11 @@ describe('useQuery().promise', () => { withinDOM().getByText('loading..') expect(renderedComponents).toEqual([Page, Loading]) } - + { const { renderedComponents, withinDOM } = await renderStream.takeRender() withinDOM().getByText('test') - expect(renderedComponents).toEqual([Page, MyComponent]) + expect(renderedComponents).toEqual([MyComponent]) } }) @@ -1035,10 +1037,11 @@ describe('useQuery().promise', () => { expect(queryFn).toHaveBeenCalledTimes(0) }) - it('should show correct data when switching between cache entries without re-fetches', async () => { + it.only('should show correct data when switching between cache entries without re-fetches', async () => { const key = queryKey() const renderStream = createRenderStream({ snapshotDOM: true }) + function MyComponent(props: { promise: Promise }) { useTrackRenders() const data = React.use(props.promise) @@ -1091,7 +1094,15 @@ describe('useQuery().promise', () => { expect(renderedComponents).toEqual([MyComponent]) } - rendered.getByText('inc').click() + { + rendered.getByText('inc').click() + + const { renderedComponents, withinDOM } = await renderStream.takeRender() + withinDOM().getByText('test0') + console.log({renderedComponents}) + expect(renderedComponents).toEqual([Page, MyComponent]) + + } { const { renderedComponents, withinDOM } = await renderStream.takeRender() diff --git a/packages/react-query/src/__tests__/utils.tsx b/packages/react-query/src/__tests__/utils.tsx index 7e25177768..29105208b6 100644 --- a/packages/react-query/src/__tests__/utils.tsx +++ b/packages/react-query/src/__tests__/utils.tsx @@ -94,3 +94,16 @@ export function setIsServer(isServer: boolean) { } export const doNotExecute = (_func: () => void) => true + + +export function createDeferred() { + let resolve: (value: TValue) => void; + let reject: (error: unknown) => void; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + + return { promise, resolve: resolve!, reject: reject! }; +} +export type Deferred = ReturnType>; \ No newline at end of file diff --git a/packages/react-query/src/useBaseQuery.ts b/packages/react-query/src/useBaseQuery.ts index bcbf700ef7..ea865322b3 100644 --- a/packages/react-query/src/useBaseQuery.ts +++ b/packages/react-query/src/useBaseQuery.ts @@ -82,28 +82,41 @@ export function useBaseQuery< ), ) - const result = observer.getOptimisticResult(defaultedOptions) - - React.useSyncExternalStore( - React.useCallback( - (onStoreChange) => { - const unsubscribe = isRestoring - ? noop - : observer.subscribe(notifyManager.batchCalls(onStoreChange)) - - // Update result to make sure we did not miss any query updates - // between creating the observer and subscribing to it. - observer.updateResult() - - return unsubscribe - }, - [observer, isRestoring], - ), - () => observer.getCurrentResult(), - () => observer.getCurrentResult(), - ) + const [result, setResult] = React.useState(() => observer.getOptimisticResult(defaultedOptions)) + + // console.log('result', result) + React.useEffect(() => { + if (isRestoring) { + return + } + console.log('subscribing to observer') + + + const unsubscribe = observer.subscribe( + notifyManager.batchCalls((newResult) => { + + setResult((prev) => { + console.log('got new result', { + prev, + newResult, + }) + return newResult + + + }) + }) + ) + + // Update result to make sure we did not miss any query updates + // between creating the observer and subscribing to it. + observer.updateResult() + + return unsubscribe + }, [observer, isRestoring]) + React.useEffect(() => { + console.log('setting options', defaultedOptions) // Do not notify on updates because of changes in the options because // these changes should already be reflected in the optimistic result. observer.setOptions(defaultedOptions, { listeners: false }) diff --git a/packages/react-query/vite.config.ts b/packages/react-query/vite.config.ts index fba5f8d044..9edede43c7 100644 --- a/packages/react-query/vite.config.ts +++ b/packages/react-query/vite.config.ts @@ -7,7 +7,6 @@ export default defineConfig({ test: { name: packageJson.name, dir: './src', - watch: false, environment: 'jsdom', setupFiles: ['test-setup.ts'], coverage: { enabled: true, provider: 'istanbul', include: ['src/**/*'] },