From 793d4dc431b1b706828fea96e9916e9def97826c Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Mon, 4 Dec 2023 11:48:31 +0000 Subject: [PATCH 1/2] fix(reactivity): fix error when using Proxy on reactive arrays --- packages/reactivity/__tests__/reactiveArray.spec.ts | 9 +++++++++ packages/reactivity/src/baseHandlers.ts | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/packages/reactivity/__tests__/reactiveArray.spec.ts b/packages/reactivity/__tests__/reactiveArray.spec.ts index 808c5aa5529..f871253b96b 100644 --- a/packages/reactivity/__tests__/reactiveArray.spec.ts +++ b/packages/reactivity/__tests__/reactiveArray.spec.ts @@ -142,6 +142,15 @@ describe('reactivity/reactive/Array', () => { expect(length).toBe('01') }) + // #9742 + test('Array can be proxied', () => { + const array = reactive([]) + const proxy = new Proxy(array, {}) + proxy.push(1) + expect(array).toHaveLength(1) + expect(proxy).toHaveLength(1) + }) + describe('Array methods w/ refs', () => { let original: any[] beforeEach(() => { diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index fa7ebbb7d75..8c85507f9ae 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -116,6 +116,10 @@ class BaseReactiveHandler implements ProxyHandler { } const targetIsArray = isArray(target) + // #9742 if the target is array prevent and we retriving the RAW, retrieve the correct target + if (key === ReactiveFlags.RAW && targetIsArray) { + return target + } if (!isReadonly) { if (targetIsArray && hasOwn(arrayInstrumentations, key)) { From 2261ade9b8c1829d8e8084c867e922dad4b6e855 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Tue, 5 Dec 2023 08:46:56 +0000 Subject: [PATCH 2/2] fix: support for prototype --- packages/reactivity/__tests__/reactiveArray.spec.ts | 8 ++++++++ packages/reactivity/src/baseHandlers.ts | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/reactivity/__tests__/reactiveArray.spec.ts b/packages/reactivity/__tests__/reactiveArray.spec.ts index f871253b96b..8686f60c7e2 100644 --- a/packages/reactivity/__tests__/reactiveArray.spec.ts +++ b/packages/reactivity/__tests__/reactiveArray.spec.ts @@ -151,6 +151,14 @@ describe('reactivity/reactive/Array', () => { expect(proxy).toHaveLength(1) }) + test('toRaw on array using reactive as prototype', () => { + const original = reactive([]) + const obj = Object.create(original) + const raw = toRaw(obj) + expect(raw).toBe(obj) + expect(raw).not.toBe(toRaw(original)) + }) + describe('Array methods w/ refs', () => { let original: any[] beforeEach(() => { diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index 8c85507f9ae..a5fde6273fa 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -117,7 +117,8 @@ class BaseReactiveHandler implements ProxyHandler { const targetIsArray = isArray(target) // #9742 if the target is array prevent and we retriving the RAW, retrieve the correct target - if (key === ReactiveFlags.RAW && targetIsArray) { + // if receiver is not an array is probably based on prototype. + if (key === ReactiveFlags.RAW && targetIsArray && isArray(receiver)) { return target }