From 313e4bf55214ac1e334a99c329a3ba5daca4f156 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 29 Aug 2024 14:10:29 +0800 Subject: [PATCH] fix(reactivity): avoid infinite recursion when mutating ref wrapped in reactive close #11696 --- packages/reactivity/__tests__/reactive.spec.ts | 9 +++++++++ packages/reactivity/src/baseHandlers.ts | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/reactivity/__tests__/reactive.spec.ts b/packages/reactivity/__tests__/reactive.spec.ts index 1c25c49121b..a90ea27f138 100644 --- a/packages/reactivity/__tests__/reactive.spec.ts +++ b/packages/reactivity/__tests__/reactive.spec.ts @@ -382,4 +382,13 @@ describe('reactivity/reactive', () => { count++ } }) + + // #11696 + test('should use correct receiver on set handler for refs', () => { + const a = reactive(ref(1)) + effect(() => a.value) + expect(() => { + a.value++ + }).not.toThrow() + }) }) diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index 8f21e354002..5916c0b5d81 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -165,7 +165,12 @@ class MutableReactiveHandler extends BaseReactiveHandler { isArray(target) && isIntegerKey(key) ? Number(key) < target.length : hasOwn(target, key) - const result = Reflect.set(target, key, value, receiver) + const result = Reflect.set( + target, + key, + value, + isRef(target) ? target : receiver, + ) // don't trigger if target is something up in the prototype chain of original if (target === toRaw(receiver)) { if (!hadKey) {