From 7fa244fa61a01ae015f6758c31127bfd6e3936cc Mon Sep 17 00:00:00 2001 From: Cody Bennett Date: Tue, 14 Feb 2023 00:56:55 -0600 Subject: [PATCH] fix: skip circular onUpdate calls (#2753) --- packages/fiber/src/core/utils.ts | 6 ++++-- packages/fiber/tests/core/renderer.test.tsx | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/fiber/src/core/utils.ts b/packages/fiber/src/core/utils.ts index 9ab78cab8a..c08143f362 100644 --- a/packages/fiber/src/core/utils.ts +++ b/packages/fiber/src/core/utils.ts @@ -354,8 +354,10 @@ export function applyProps(instance: Instance, data: InstanceProps | DiffSet) { if (localState.eventCount) rootState.internal.interaction.push(instance as unknown as THREE.Object3D) } - // Call the update lifecycle when it is being updated, but only when it is part of the scene - if (changes.length && instance.__r3f?.parent) updateInstance(instance) + // Call the update lifecycle when it is being updated, but only when it is part of the scene. + // Skip updates to the `onUpdate` prop itself + const isCircular = changes.length === 1 && changes[0][0] === 'onUpdate' + if (!isCircular && changes.length && instance.__r3f?.parent) updateInstance(instance) return instance } diff --git a/packages/fiber/tests/core/renderer.test.tsx b/packages/fiber/tests/core/renderer.test.tsx index 0c3229d2d4..c35e79271c 100644 --- a/packages/fiber/tests/core/renderer.test.tsx +++ b/packages/fiber/tests/core/renderer.test.tsx @@ -849,4 +849,16 @@ describe('renderer', () => { expect(ref.current!.scale.toArray()).toStrictEqual(new THREE.Object3D().scale.toArray()) }) + + it("onUpdate shouldn't update itself", async () => { + const one = jest.fn() + const two = jest.fn() + + const Test = (props: Partial) => + await act(async () => root.render()) + await act(async () => root.render()) + + expect(one).toBeCalledTimes(1) + expect(two).toBeCalledTimes(0) + }) })