Skip to content

Commit a46ba65

Browse files
authored
fix: replaceDeepEqual special case for non-plain arrays (TanStack#3669)
* Fix case where replaceDeepEqual was returning incorrect value for non-plain arrays * fix pr comments
1 parent 97484dc commit a46ba65

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

src/core/tests/utils.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
matchMutation,
77
scheduleMicrotask,
88
sleep,
9+
isPlainArray,
910
} from '../utils'
1011
import { Mutation } from '../mutation'
1112
import { createQueryClient } from '../../tests/utils'
@@ -56,6 +57,16 @@ describe('core/utils', () => {
5657
})
5758
})
5859

60+
describe('isPlainArray', () => {
61+
it('should return `true` for plain arrays', () => {
62+
expect(isPlainArray([1, 2])).toEqual(true)
63+
})
64+
65+
it('should return `false` for non plain arrays', () => {
66+
expect(isPlainArray(Object.assign([1, 2], { a: 'b' }))).toEqual(false)
67+
})
68+
})
69+
5970
describe('partialDeepEqual', () => {
6071
it('should return `true` if a includes b', () => {
6172
const a = { a: { b: 'b' }, c: 'c', d: [{ d: 'd ' }] }
@@ -258,6 +269,13 @@ describe('core/utils', () => {
258269
expect(result[1]).toBe(prev[1])
259270
})
260271

272+
it('should support objects which are not plain arrays', () => {
273+
const prev = Object.assign([1, 2], { a: { b: 'b' }, c: 'c' })
274+
const next = Object.assign([1, 2], { a: { b: 'b' }, c: 'c' })
275+
const result = replaceEqualDeep(prev, next)
276+
expect(result).toBe(next)
277+
})
278+
261279
it('should replace all parent objects if some nested value changes', () => {
262280
const prev = {
263281
todo: { id: '1', meta: { createdAt: 0 }, state: { done: false } },

src/core/utils.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ export function replaceEqualDeep(a: any, b: any): any {
314314
return a
315315
}
316316

317-
const array = Array.isArray(a) && Array.isArray(b)
317+
const array = isPlainArray(a) && isPlainArray(b)
318318

319319
if (array || (isPlainObject(a) && isPlainObject(b))) {
320320
const aSize = array ? a.length : Object.keys(a).length
@@ -355,6 +355,10 @@ export function shallowEqualObjects<T>(a: T, b: T): boolean {
355355
return true
356356
}
357357

358+
export function isPlainArray(value: unknown) {
359+
return Array.isArray(value) && value.length === Object.keys(value).length
360+
}
361+
358362
// Copied from: https://github.com/jonschlinkert/is-plain-object
359363
export function isPlainObject(o: any): o is Object {
360364
if (!hasObjectPrototype(o)) {

0 commit comments

Comments
 (0)