From 837c1b84c91ef17dbae033d9c10b95405a29a4f1 Mon Sep 17 00:00:00 2001 From: Precious void <20266461+precious-void@users.noreply.github.com> Date: Mon, 20 May 2024 23:06:55 +0300 Subject: [PATCH 1/2] fix: immediate setState in useEffect for unstable_validateStringsRenderedWithinText --- .../render-string-validation.test.tsx | 46 +++++++++++++++++++ src/render.tsx | 10 ++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/__tests__/render-string-validation.test.tsx b/src/__tests__/render-string-validation.test.tsx index 259e26c93..2eba3ab27 100644 --- a/src/__tests__/render-string-validation.test.tsx +++ b/src/__tests__/render-string-validation.test.tsx @@ -155,3 +155,49 @@ test('should throw when rendering string in a View in a Text', () => { `${VALIDATION_ERROR}. Detected attempt to render "hello" string within a component.`, ); }); + +const UseEffectComponent = () => { + const [showText, setShowText] = React.useState(false); + + React.useEffect(() => { + setShowText(true); + }, []); + + if (!showText) { + return Text is hidden; + } + + return ( + + Text is visible + + ); +}; + +test('should render immediate setState in useEffect properly', async () => { + render(, { unstable_validateStringsRenderedWithinText: true }); + + expect(await screen.findByText('Text is visible')).toBeTruthy(); +}); + +const InvalidUseEffectComponent = () => { + const [showText, setShowText] = React.useState(false); + + React.useEffect(() => { + setShowText(true); + }, []); + + if (!showText) { + return Text is hidden; + } + + return Text is visible; +}; + +test('should throw properly for immediate setState in useEffect', () => { + expect(() => + render(, { unstable_validateStringsRenderedWithinText: true }), + ).toThrow( + `${VALIDATION_ERROR}. Detected attempt to render "Text is visible" string within a component.`, + ); +}); diff --git a/src/render.tsx b/src/render.tsx index a73addbe4..4b6fb04c0 100644 --- a/src/render.tsx +++ b/src/render.tsx @@ -10,7 +10,7 @@ import debugShallow from './helpers/debug-shallow'; import { configureHostComponentNamesIfNeeded } from './helpers/host-component-names'; import { validateStringsRenderedWithinText } from './helpers/string-validation'; import { renderWithAct } from './render-act'; -import { setRenderResult, screen } from './screen'; +import { setRenderResult } from './screen'; import { getQueriesForElement } from './within'; export interface RenderOptions { @@ -64,11 +64,12 @@ function renderWithStringValidation( component: React.ReactElement, options: Omit = {}, ) { + let renderer: ReactTestRenderer; const { wrapper: Wrapper, ...testRendererOptions } = options ?? {}; const handleRender: React.ProfilerProps['onRender'] = (_, phase) => { - if (phase === 'update') { - validateStringsRenderedWithinText(screen.toJSON()); + if (renderer && phase === 'update') { + validateStringsRenderedWithinText(renderer.toJSON()); } }; @@ -78,7 +79,8 @@ function renderWithStringValidation( ); - const renderer = renderWithAct(wrap(component), testRendererOptions); + renderer = renderWithAct(wrap(component), testRendererOptions); + validateStringsRenderedWithinText(renderer.toJSON()); return buildRenderResult(renderer, wrap); From 3a54e2e662270bd084da8386c2c7815f70085574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Thu, 23 May 2024 12:14:21 +0200 Subject: [PATCH 2/2] refactor: tweaks --- src/render.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render.tsx b/src/render.tsx index 4b6fb04c0..69d27b53e 100644 --- a/src/render.tsx +++ b/src/render.tsx @@ -67,7 +67,7 @@ function renderWithStringValidation( let renderer: ReactTestRenderer; const { wrapper: Wrapper, ...testRendererOptions } = options ?? {}; - const handleRender: React.ProfilerProps['onRender'] = (_, phase) => { + const handleRender: React.ProfilerOnRenderCallback = (_, phase) => { if (renderer && phase === 'update') { validateStringsRenderedWithinText(renderer.toJSON()); }