Skip to content

Commit 8a9576a

Browse files
committed
Testing render behaviour
1 parent 0b5f0c3 commit 8a9576a

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

tests/index.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,79 @@ it("should be able to render without mock defaults", async () => {
259259
await delay(50);
260260
assertSize({ width: 100, height: 100 });
261261
});
262+
263+
it("should not trigger unnecessary renders with the same width or height", async () => {
264+
const Test = ({ resolveHandler }) => {
265+
return (
266+
<div style={{ position: "relative" }} id="container">
267+
<Observed resolveHandler={resolveHandler} />
268+
</div>
269+
);
270+
};
271+
272+
// Setting the size like this won't trigger any unnecessary re-renders within
273+
// the components, so we can accurately measure renders being triggered by the
274+
// hook itself.
275+
const setSize = ({ width, height }) => {
276+
const container = document.querySelector("#container");
277+
container.style.width = `${width}px`;
278+
container.style.height = `${height}px`;
279+
};
280+
const { assertSize, assertRenderCount } = await render(Test);
281+
282+
assertSize({ width: 1, height: 1 });
283+
assertRenderCount(1);
284+
285+
await delay(50);
286+
assertRenderCount(2);
287+
288+
setSize({ width: 100, height: 102 });
289+
await delay(50);
290+
assertSize({ width: 100, height: 102 });
291+
assertRenderCount(3);
292+
293+
// Shouldn't trigger on subpixel values that are rounded to be the same as the
294+
// previous size
295+
setSize({ width: 100.4, height: 102.4 });
296+
await delay(50);
297+
assertSize({ width: 100, height: 102 });
298+
assertRenderCount(3);
299+
});
300+
301+
it("should keep the same response instance between renders if nothing changed", async () => {
302+
const Test = ({ resolveHandler }) => {
303+
const previousResponseRef = useRef(null);
304+
const response = useResizeObserver({ useDefaults: false });
305+
const [state, setState] = useState(false);
306+
307+
const sameInstance = previousResponseRef.current === response;
308+
previousResponseRef.current = response;
309+
310+
useEffect(() => {
311+
if (response.width && response.height) {
312+
// Triggering an extra render once the hook properly measured the element size once.
313+
// This'll allow us to see if the hook keeps the same response object or not.
314+
setState(true);
315+
}
316+
}, [response]);
317+
318+
useEffect(() => {
319+
if (!state) {
320+
return;
321+
}
322+
323+
// Everything is set up, ready for assertions
324+
resolveHandler({
325+
assertSameInstance: () => {
326+
expect(sameInstance).toBe(true);
327+
}
328+
});
329+
}, [state]);
330+
331+
return <div ref={response.ref}>{String(sameInstance)}</div>;
332+
};
333+
334+
const { assertSameInstance } = await render(Test);
335+
336+
assertSameInstance();
337+
});

0 commit comments

Comments
 (0)