Skip to content

Commit 76de7d2

Browse files
fix: immediate setState in useEffect for unstable_validateStringsRenderedWithinText (#1612)
* fix: immediate setState in useEffect for unstable_validateStringsRenderedWithinText * refactor: tweaks --------- Co-authored-by: Maciej Jastrzębski <mdjastrzebski@gmail.com>
1 parent 1b732d6 commit 76de7d2

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

src/__tests__/render-string-validation.test.tsx

+46
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,49 @@ test('should throw when rendering string in a View in a Text', () => {
155155
`${VALIDATION_ERROR}. Detected attempt to render "hello" string within a <View> component.`,
156156
);
157157
});
158+
159+
const UseEffectComponent = () => {
160+
const [showText, setShowText] = React.useState(false);
161+
162+
React.useEffect(() => {
163+
setShowText(true);
164+
}, []);
165+
166+
if (!showText) {
167+
return <Text>Text is hidden</Text>;
168+
}
169+
170+
return (
171+
<View>
172+
<Text>Text is visible</Text>
173+
</View>
174+
);
175+
};
176+
177+
test('should render immediate setState in useEffect properly', async () => {
178+
render(<UseEffectComponent />, { unstable_validateStringsRenderedWithinText: true });
179+
180+
expect(await screen.findByText('Text is visible')).toBeTruthy();
181+
});
182+
183+
const InvalidUseEffectComponent = () => {
184+
const [showText, setShowText] = React.useState(false);
185+
186+
React.useEffect(() => {
187+
setShowText(true);
188+
}, []);
189+
190+
if (!showText) {
191+
return <Text>Text is hidden</Text>;
192+
}
193+
194+
return <View>Text is visible</View>;
195+
};
196+
197+
test('should throw properly for immediate setState in useEffect', () => {
198+
expect(() =>
199+
render(<InvalidUseEffectComponent />, { unstable_validateStringsRenderedWithinText: true }),
200+
).toThrow(
201+
`${VALIDATION_ERROR}. Detected attempt to render "Text is visible" string within a <View> component.`,
202+
);
203+
});

src/render.tsx

+7-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import debugShallow from './helpers/debug-shallow';
1010
import { configureHostComponentNamesIfNeeded } from './helpers/host-component-names';
1111
import { validateStringsRenderedWithinText } from './helpers/string-validation';
1212
import { renderWithAct } from './render-act';
13-
import { setRenderResult, screen } from './screen';
13+
import { setRenderResult } from './screen';
1414
import { getQueriesForElement } from './within';
1515

1616
export interface RenderOptions {
@@ -64,11 +64,12 @@ function renderWithStringValidation<T>(
6464
component: React.ReactElement<T>,
6565
options: Omit<RenderOptions, 'unstable_validateStringsRenderedWithinText'> = {},
6666
) {
67+
let renderer: ReactTestRenderer;
6768
const { wrapper: Wrapper, ...testRendererOptions } = options ?? {};
6869

69-
const handleRender: React.ProfilerProps['onRender'] = (_, phase) => {
70-
if (phase === 'update') {
71-
validateStringsRenderedWithinText(screen.toJSON());
70+
const handleRender: React.ProfilerOnRenderCallback = (_, phase) => {
71+
if (renderer && phase === 'update') {
72+
validateStringsRenderedWithinText(renderer.toJSON());
7273
}
7374
};
7475

@@ -78,7 +79,8 @@ function renderWithStringValidation<T>(
7879
</Profiler>
7980
);
8081

81-
const renderer = renderWithAct(wrap(component), testRendererOptions);
82+
renderer = renderWithAct(wrap(component), testRendererOptions);
83+
8284
validateStringsRenderedWithinText(renderer.toJSON());
8385

8486
return buildRenderResult(renderer, wrap);

0 commit comments

Comments
 (0)