Skip to content

Commit

Permalink
fix: skip circular onUpdate calls (#2753)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodyJasonBennett committed Feb 14, 2023
1 parent 7b25689 commit 7fa244f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 2 deletions.
6 changes: 4 additions & 2 deletions packages/fiber/src/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
12 changes: 12 additions & 0 deletions packages/fiber/tests/core/renderer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<JSX.IntrinsicElements['mesh']>) => <mesh {...props} />
await act(async () => root.render(<Test onUpdate={one} />))
await act(async () => root.render(<Test onUpdate={two} />))

expect(one).toBeCalledTimes(1)
expect(two).toBeCalledTimes(0)
})
})

0 comments on commit 7fa244f

Please sign in to comment.