diff --git a/src/queryCache.js b/src/queryCache.js index 06fabe5dae..677795cc3a 100644 --- a/src/queryCache.js +++ b/src/queryCache.js @@ -289,9 +289,6 @@ export function makeQueryCache() { } query.updateInstance = instance => { - // Filter out any placeholder instances created for suspense - query.instances = query.instances.filter(d => !d.isPlaceholder) - let found = query.instances.find(d => d.id === instance.id) if (found) { @@ -310,9 +307,7 @@ export function makeQueryCache() { // Return the unsubscribe function return () => { - query.instances = query.instances.filter( - d => !d.isPlaceholder && d.id !== instanceId - ) + query.instances = query.instances.filter(d => d.id !== instanceId) if (!query.instances.length) { // Cancel any side-effects @@ -406,6 +401,12 @@ export function makeQueryCache() { // If there are any retries pending for this query, kill them query.cancelled = null + const callbackInstances = [...query.instances] + + if (query.wasSuspended) { + callbackInstances.unshift(query.suspenseInstance) + } + try { // Set up the query refreshing state dispatch({ type: actionFetch }) @@ -421,12 +422,12 @@ export function makeQueryCache() { query.config.isDataEqual(old, data) ? old : data ) - query.instances.forEach( + callbackInstances.forEach( instance => instance.onSuccess && instance.onSuccess(query.state.data) ) - query.instances.forEach( + callbackInstances.forEach( instance => instance.onSettled && instance.onSettled(query.state.data, null) ) @@ -444,11 +445,11 @@ export function makeQueryCache() { delete query.promise if (error !== query.cancelled) { - query.instances.forEach( + callbackInstances.forEach( instance => instance.onError && instance.onError(error) ) - query.instances.forEach( + callbackInstances.forEach( instance => instance.onSettled && instance.onSettled(undefined, error) ) diff --git a/src/tests/useQuery.test.js b/src/tests/useQuery.test.js index 9b56bf757d..2c230b43d7 100644 --- a/src/tests/useQuery.test.js +++ b/src/tests/useQuery.test.js @@ -337,14 +337,7 @@ describe('useQuery', () => { await waitForElement(() => rendered.getByText('todo aaaa')) - console.log(queryCache.queries) - - // TODO: This passes in node 10 and 12 both locally and in CI, - // but fails in CI when using node 12.... Not sure what to do here. - - // FYI, it thinks that it's equal to 2, not 1 - - // expect(Object.keys(queryCache.queries).length).toEqual(1) + expect(Object.keys(queryCache.queries).length).toEqual(1) }) // See https://github.com/tannerlinsley/react-query/issues/160 diff --git a/src/useBaseQuery.js b/src/useBaseQuery.js index 90d62bfcf3..683fc3b4c1 100644 --- a/src/useBaseQuery.js +++ b/src/useBaseQuery.js @@ -60,30 +60,25 @@ export function useBaseQuery(queryKey, queryVariables, queryFn, config = {}) { [query] ) - const updateInstance = React.useCallback( - isPlaceholder => { - query.updateInstance({ - id: instanceId, - isPlaceholder, - onStateUpdate: () => rerender({}), - onSuccess: data => getLatestConfig().onSuccess(data), - onError: err => getLatestConfig().onError(err), - onSettled: (data, err) => getLatestConfig().onSettled(data, err), - }) - }, - [getLatestConfig, instanceId, query, rerender] - ) - - // Create the placeholder instance of this query (suspense needs this to - // to fire things like onSuccess/onError/onSettled) - updateInstance(true) + query.suspenseInstance = { + onSuccess: data => getLatestConfig().onSuccess(data), + onError: err => getLatestConfig().onError(err), + onSettled: (data, err) => getLatestConfig().onSettled(data, err), + } // After mount, subscribe to the query React.useEffect(() => { // Update the instance to the query again, but not as a placeholder - updateInstance() + query.updateInstance({ + id: instanceId, + onStateUpdate: () => rerender({}), + onSuccess: data => getLatestConfig().onSuccess(data), + onError: err => getLatestConfig().onError(err), + onSettled: (data, err) => getLatestConfig().onSettled(data, err), + }) + return query.subscribe(instanceId) - }, [getLatestConfig, instanceId, query, rerender, updateInstance]) + }, [getLatestConfig, instanceId, query, rerender]) React.useEffect(() => { // Perform the initial fetch for this query if necessary @@ -92,8 +87,7 @@ export function useBaseQuery(queryKey, queryVariables, queryFn, config = {}) { !query.wasPrefetched && // Don't double fetch for prefetched queries !query.wasSuspended && // Don't double fetch for suspense query.state.isStale && // Only refetch if stale - (getLatestConfig().refetchOnMount || - query.instances.filter(d => !d.isPlaceholder).length === 1) + (getLatestConfig().refetchOnMount || query.instances.length === 1) ) { refetch().catch(Console.error) }