fix(reactivity): ensure the first parameter in the reduce callback is reactive

This commit is contained in:
inottn 2025-01-18 16:25:28 +08:00
parent 82da43d167
commit 00f3f576f7
2 changed files with 25 additions and 1 deletions

View File

@ -623,7 +623,7 @@ describe('reactivity/reactive/Array', () => {
expect(left.value).toBe(shallow[0]) expect(left.value).toBe(shallow[0])
expect(right.value).toBe(shallow[0]) expect(right.value).toBe(shallow[0])
const deep = reactive([{ val: 1 }, { val: 2 }]) let deep = reactive([{ val: 1 }, { val: 2 }])
left = computed(() => deep.reduce((acc, x) => acc + x.val, '0')) left = computed(() => deep.reduce((acc, x) => acc + x.val, '0'))
right = computed(() => deep.reduceRight((acc, x) => acc + x.val, '3')) right = computed(() => deep.reduceRight((acc, x) => acc + x.val, '3'))
expect(left.value).toBe('012') expect(left.value).toBe('012')
@ -632,6 +632,25 @@ describe('reactivity/reactive/Array', () => {
deep[1].val = 23 deep[1].val = 23
expect(left.value).toBe('0123') expect(left.value).toBe('0123')
expect(right.value).toBe('3231') expect(right.value).toBe('3231')
deep = reactive([{ val: 1 }, { val: 2 }])
const maxBy = (prev: any, cur: any) => {
expect(isReactive(prev)).toBe(true)
expect(isReactive(cur)).toBe(true)
return prev.val > cur.val ? prev : cur
}
left = computed(() => deep.reduce(maxBy))
right = computed(() => deep.reduceRight(maxBy))
expect(left.value).toMatchObject({ val: 2 })
expect(right.value).toMatchObject({ val: 2 })
deep[0].val = 23
expect(left.value).toMatchObject({ val: 23 })
expect(right.value).toMatchObject({ val: 23 })
deep[1].val = 24
expect(left.value).toMatchObject({ val: 24 })
expect(right.value).toMatchObject({ val: 24 })
}) })
test('some', () => { test('some', () => {

View File

@ -280,7 +280,12 @@ function reduce(
let wrappedFn = fn let wrappedFn = fn
if (arr !== self) { if (arr !== self) {
if (!isShallow(self)) { if (!isShallow(self)) {
let needReactive = args.length === 0
wrappedFn = function (this: unknown, acc, item, index) { wrappedFn = function (this: unknown, acc, item, index) {
if (needReactive) {
needReactive = false
acc = toReactive(acc)
}
return fn.call(this, acc, toReactive(item), index, self) return fn.call(this, acc, toReactive(item), index, self)
} }
} else if (fn.length > 3) { } else if (fn.length > 3) {