Skip to content

Commit c376158

Browse files
authored
feat: add deprecation warnings
* feat: deprecate isDataEqual * feat: deprecate contextSharing * feat: deprecate custom loggers * test: fix ssr-hydration tests we need to compare against actual console.log here (and not our own logger), because react hydration mismatches are also logged to the console if they exist. This has surfaced another issue because of how we import react for react17/18 differential testing. * fix: remove useEffect that would wind up empty in production, and since this is just during development mode, we can just log during render * test: adapt tests we can remove most of these in v5 * chore: fix console.mock declaration * feat: deprecate placeholder data function * chore: scope test execution to src directories if we do `pnpm test` locally, it first does typechecking, which produces output in `build` (including test files). Those will then be tested as well and the svelte tests fail with that. * test: fix vue query test * un-deprecate placeholderData function we might still need it after all - to be discussed * un-deprecate placeholderData function * fix auto import
1 parent e152ea5 commit c376158

File tree

17 files changed

+105
-20
lines changed

17 files changed

+105
-20
lines changed

docs/guides/custom-logger.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,8 @@ const queryClient = new QueryClient({
2020
},
2121
})
2222
```
23+
24+
**Deprecated**
25+
26+
Custom loggers have been deprecated and will be removed in the next major version.
27+
Logging only has an effect in development mode, where passing a custom logger is not necessary.

docs/guides/placeholder-query-data.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ function Todos() {
2828
}
2929
```
3030

31-
### Placeholder Data as a Function
31+
### Placeholder Data Memoization
3232

33-
If the process for accessing a query's placeholder data is intensive or just not something you want to perform on every render, you can memoize the value or pass a memoized function as the `placeholderData` value:
33+
If the process for accessing a query's placeholder data is intensive or just not something you want to perform on every render, you can memoize the value:
3434

3535
```tsx
3636
function Todos() {

docs/reference/QueryClientProvider.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ function App() {
2121
- **Required**
2222
- the QueryClient instance to provide
2323
- `contextSharing: boolean`
24+
- **Deprecated**
2425
- defaults to `false`
2526
- Set this to `true` to enable context sharing, which will share the first and at least one instance of the context across the window to ensure that if React Query is used across different bundles or microfrontends they will all use the same **instance** of context, regardless of module scoping.
2627
- `context?: React.Context<QueryClient | undefined>`

docs/reference/useQuery.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ const {
3636
networkMode,
3737
initialData,
3838
initialDataUpdatedAt,
39-
isDataEqual,
4039
keepPreviousData,
4140
meta,
4241
notifyOnChangeProps,
@@ -171,6 +170,8 @@ const {
171170
- Defaults to `false`
172171
- If set, any previous `data` will be kept when fetching new data because the query key changed.
173172
- `isDataEqual: (oldData: TData | undefined, newData: TData) => boolean`
173+
- **Deprecated**. You can achieve the same functionality by passing a function to `structuralSharing` instead:
174+
- structuralSharing: (oldData, newData) => isDataEqual(oldData, newData) ? oldData : replaceEqualDeep(oldData, newData)
174175
- Optional
175176
- This function should return boolean indicating whether to use previous `data` (`true`) or new data (`false`) as a resolved data for the query.
176177
- `structuralSharing: boolean | ((oldData: TData | undefined, newData: TData) => TData)`

jest-preset.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const moduleNameMapper = {
2424
module.exports = {
2525
collectCoverage: true,
2626
coverageReporters: ['json', 'lcov', 'text', 'clover', 'text-summary'],
27-
testMatch: ['<rootDir>/**/*.test.[jt]s?(x)'],
27+
testMatch: ['<rootDir>/**/src/**/*.test.[jt]s?(x)'],
2828
transform: { '^.+\\.(ts|tsx)$': 'ts-jest' },
2929
clearMocks: true,
3030
testEnvironment: 'jsdom',

packages/query-core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export { focusManager } from './focusManager'
1313
export { onlineManager } from './onlineManager'
1414
export {
1515
hashQueryKey,
16+
replaceEqualDeep,
1617
isError,
1718
isServer,
1819
parseQueryArgs,

packages/query-core/src/queryClient.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ export class QueryClient {
7171
this.defaultOptions = config.defaultOptions || {}
7272
this.queryDefaults = []
7373
this.mutationDefaults = []
74+
75+
if (process.env.NODE_ENV !== 'production' && config.logger) {
76+
this.logger.error(
77+
`Passing a custom logger has been deprecated and will be removed in the next major version.`,
78+
)
79+
}
7480
}
7581

7682
mount(): void {

packages/query-core/src/queryObserver.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,17 @@ export class QueryObserver<
155155

156156
this.options = this.client.defaultQueryOptions(options)
157157

158+
if (
159+
process.env.NODE_ENV !== 'production' &&
160+
typeof options?.isDataEqual !== 'undefined'
161+
) {
162+
this.client
163+
.getLogger()
164+
.error(
165+
`The isDataEqual option has been deprecated and will be removed in the next major version. You can achieve the same functionality by passing a function as the structuralSharing option`,
166+
)
167+
}
168+
158169
if (!shallowEqualObjects(prevOptions, this.options)) {
159170
this.client.getQueryCache().notify({
160171
type: 'observerOptionsUpdated',

packages/query-core/src/tests/queriesObserver.test.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,13 @@ describe('queriesObserver', () => {
5050
unsubscribe()
5151
expect(observerResult).toMatchObject([{ data: 1 }, { data: 2 }])
5252

53-
expect(mockLogger.error).toHaveBeenCalledTimes(1)
53+
expect(mockLogger.error).toHaveBeenCalledTimes(2)
54+
expect(mockLogger.error).toHaveBeenCalledWith(
55+
'Passing a custom logger has been deprecated and will be removed in the next major version.',
56+
)
57+
expect(mockLogger.error).toHaveBeenCalledWith(
58+
'Passing a custom logger has been deprecated and will be removed in the next major version.',
59+
)
5460
})
5561

5662
test('should update when a query updates', async () => {

packages/query-core/src/tests/queryClient.test.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ describe('queryClient', () => {
160160
// No defaults, no warning
161161
const noDefaults = queryClient.getQueryDefaults(keyABCD)
162162
expect(noDefaults).toBeUndefined()
163-
expect(mockLogger.error).not.toHaveBeenCalled()
163+
expect(mockLogger.error).toHaveBeenCalledTimes(1)
164164

165165
// If defaults for key ABCD are registered **before** the ones of key ABC (more generic)…
166166
queryClient.setQueryDefaults(keyABCD, defaultsOfABCD)
@@ -169,7 +169,7 @@ describe('queryClient', () => {
169169
const goodDefaults = queryClient.getQueryDefaults(keyABCD)
170170
expect(goodDefaults).toBe(defaultsOfABCD)
171171
// The warning is still raised since several defaults are matching
172-
expect(mockLogger.error).toHaveBeenCalledTimes(1)
172+
expect(mockLogger.error).toHaveBeenCalledTimes(2)
173173

174174
// Let's create another queryClient and change the order of registration
175175
const newQueryClient = createQueryClient()
@@ -180,7 +180,7 @@ describe('queryClient', () => {
180180
const badDefaults = newQueryClient.getQueryDefaults(keyABCD)
181181
expect(badDefaults).not.toBe(defaultsOfABCD)
182182
expect(badDefaults).toBe(defaultsOfABC)
183-
expect(mockLogger.error).toHaveBeenCalledTimes(2)
183+
expect(mockLogger.error).toHaveBeenCalledTimes(4)
184184
})
185185

186186
test('should warn in dev if several mutation defaults match a given key', () => {
@@ -216,7 +216,10 @@ describe('queryClient', () => {
216216
// No defaults, no warning
217217
const noDefaults = queryClient.getMutationDefaults(keyABCD)
218218
expect(noDefaults).toBeUndefined()
219-
expect(mockLogger.error).not.toHaveBeenCalled()
219+
expect(mockLogger.error).toHaveBeenNthCalledWith(
220+
1,
221+
'Passing a custom logger has been deprecated and will be removed in the next major version.',
222+
)
220223

221224
// If defaults for key ABCD are registered **before** the ones of key ABC (more generic)…
222225
queryClient.setMutationDefaults(keyABCD, defaultsOfABCD)
@@ -225,7 +228,7 @@ describe('queryClient', () => {
225228
const goodDefaults = queryClient.getMutationDefaults(keyABCD)
226229
expect(goodDefaults).toBe(defaultsOfABCD)
227230
// The warning is still raised since several defaults are matching
228-
expect(mockLogger.error).toHaveBeenCalledTimes(1)
231+
expect(mockLogger.error).toHaveBeenCalledTimes(2)
229232

230233
// Let's create another queryClient and change the order of registration
231234
const newQueryClient = createQueryClient()
@@ -236,7 +239,7 @@ describe('queryClient', () => {
236239
const badDefaults = newQueryClient.getMutationDefaults(keyABCD)
237240
expect(badDefaults).not.toBe(defaultsOfABCD)
238241
expect(badDefaults).toBe(defaultsOfABC)
239-
expect(mockLogger.error).toHaveBeenCalledTimes(2)
242+
expect(mockLogger.error).toHaveBeenCalledTimes(4)
240243
})
241244
})
242245

0 commit comments

Comments
 (0)