Skip to content

Commit 1bffc78

Browse files
jxomautofix-ci[bot]TkDodo
authored
fix: replace JSON.stringify with replaceDeepEqual in structural sharing integrity check (#8030)
* feat: throw when `replaceDeepEqual` contains circular references * ci: apply automated fixes * chore: up test * chore: review changes * ci: apply automated fixes * chore: add return --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Dominik Dorfmeister <office@dorfmeister.cc>
1 parent d58cf08 commit 1bffc78

File tree

2 files changed

+32
-24
lines changed

2 files changed

+32
-24
lines changed

packages/query-core/src/__tests__/query.test.tsx

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -975,36 +975,46 @@ describe('query', () => {
975975

976976
const queryFn = vi.fn()
977977

978+
const data: Array<{
979+
id: number
980+
name: string
981+
link: null | { id: number; name: string; link: unknown }
982+
}> = Array.from({ length: 5 })
983+
.fill(null)
984+
.map((_, index) => ({
985+
id: index,
986+
name: `name-${index}`,
987+
link: null,
988+
}))
989+
990+
if (data[0] && data[1]) {
991+
data[0].link = data[1]
992+
data[1].link = data[0]
993+
}
994+
978995
queryFn.mockImplementation(async () => {
979996
await sleep(10)
980-
981-
const data: Array<{
982-
id: number
983-
name: string
984-
link: null | { id: number; name: string; link: unknown }
985-
}> = Array.from({ length: 5 })
986-
.fill(null)
987-
.map((_, index) => ({
988-
id: index,
989-
name: `name-${index}`,
990-
link: null,
991-
}))
992-
993-
if (data[0] && data[1]) {
994-
data[0].link = data[1]
995-
data[1].link = data[0]
996-
}
997-
998997
return data
999998
})
1000999

1001-
await queryClient.prefetchQuery({ queryKey: key, queryFn })
1000+
await queryClient.prefetchQuery({
1001+
queryKey: key,
1002+
queryFn,
1003+
initialData: structuredClone(data),
1004+
})
1005+
1006+
const query = queryCache.find({ queryKey: key })!
10021007

10031008
expect(queryFn).toHaveBeenCalledTimes(1)
10041009

1010+
expect(query.state.status).toBe('error')
1011+
expect(
1012+
query.state.error?.message.includes('Maximum call stack size exceeded'),
1013+
).toBeTruthy()
1014+
10051015
expect(consoleMock).toHaveBeenCalledWith(
10061016
expect.stringContaining(
1007-
'StructuralSharing requires data to be JSON serializable',
1017+
'Structural sharing requires data to be JSON serializable',
10081018
),
10091019
)
10101020

packages/query-core/src/utils.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -356,15 +356,13 @@ export function replaceData<
356356
} else if (options.structuralSharing !== false) {
357357
if (process.env.NODE_ENV !== 'production') {
358358
try {
359-
JSON.stringify(prevData)
360-
JSON.stringify(data)
359+
return replaceEqualDeep(prevData, data)
361360
} catch (error) {
362361
console.error(
363-
`StructuralSharing requires data to be JSON serializable. To fix this, turn off structuralSharing or return JSON-serializable data from your queryFn. [${options.queryHash}]: ${error}`,
362+
`Structural sharing requires data to be JSON serializable. To fix this, turn off structuralSharing or return JSON-serializable data from your queryFn. [${options.queryHash}]: ${error}`,
364363
)
365364
}
366365
}
367-
368366
// Structurally share data between prev and new data if needed
369367
return replaceEqualDeep(prevData, data)
370368
}

0 commit comments

Comments
 (0)