From c925872e72d2422be46670777bfa2111e13c9e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Tue, 28 Jan 2025 07:26:23 -0800 Subject: [PATCH] Throw an error when calling root.render outside of a task (#49003) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49003 Changelog: [internal] I was adding a benchmark for rendering thousands of views and it was surprisingly fast, until I realized I wasn't wrapping the call to `root.render` in `runTask`, which means the benchmark wasn't really doing the rendering, only scheduling a microtask that was never executed. This is a safety mechanism to prevent those mistakes. Reviewed By: sammy-SC Differential Revision: D68771170 fbshipit-source-id: 5bd8e6ba9e1168db2320572c99b3a01ebd6aeeed --- .../src/__tests__/Fantom-itest.js | 16 ++++++++++++++++ packages/react-native-fantom/src/index.js | 8 +++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/react-native-fantom/src/__tests__/Fantom-itest.js b/packages/react-native-fantom/src/__tests__/Fantom-itest.js index 3eb82e160c524d..46b0304d3ca53b 100644 --- a/packages/react-native-fantom/src/__tests__/Fantom-itest.js +++ b/packages/react-native-fantom/src/__tests__/Fantom-itest.js @@ -155,6 +155,22 @@ describe('Fantom', () => { }, ); }); + + it('throws when trying to render a root outside of a task', () => { + const root = Fantom.createRoot(); + + expect(() => { + root.render(); + }).toThrow( + 'Unexpected call to `render` outside of the event loop. Please call `render` within a `runTask` callback.', + ); + + expect(() => { + Fantom.runTask(() => { + root.render(); + }); + }).not.toThrow(); + }); }); describe('getRenderedOutput', () => { diff --git a/packages/react-native-fantom/src/index.js b/packages/react-native-fantom/src/index.js index 327227d743bfd6..ddca12d3264e33 100644 --- a/packages/react-native-fantom/src/index.js +++ b/packages/react-native-fantom/src/index.js @@ -57,7 +57,13 @@ class Root { globalSurfaceIdCounter += 10; } - render(element: MixedElement) { + render(element: MixedElement): void { + if (!flushingQueue) { + throw new Error( + 'Unexpected call to `render` outside of the event loop. Please call `render` within a `runTask` callback.', + ); + } + if (!this.#hasRendered) { NativeFantom.startSurface( this.#surfaceId,