// @vitest-environment jsdom // // A store is read from React through `useValue()`, a name the React Compiler knows as a hook. Its // old name, `use()`, it did not: the call was compiled as an ordinary one and memoized, so it ran // on the first render alone. Read straight from a component, Back to top never re-rendered; // read inside a hook that compiles memo scopes around it, usePlaylistActions rendered fewer hooks // on its second render and threw (the moment that hook started to compile). Vitest builds // with the same compiler as the app (reactPlugin), so this renders the compiled code. import { describe, it, expect, afterEach } from "vitest"; import { render, screen, act, cleanup } from "@testing-library/react"; import { useState } from "react"; import { createStore } from "./store"; afterEach(cleanup); const count = createStore(0); // A hook shaped like usePlaylistActions: other hooks around the read, and a callback built from it. function useCountLabel(prefix: string) { const [step] = useState(1); const value = count.useValue(); const next = () => count.set(value + step); return { label: `${prefix}${value}`, next }; } function Counter() { const { label, next } = useCountLabel("n="); return ; } function Bare() { return {`bare=${count.useValue()}`}; } describe("a store read from React", () => { it("re-renders a compiled hook and a compiled component on every change", () => { act(() => count.set(0)); render( <> , ); act(() => count.set(1)); expect(screen.getByRole("button").textContent).toBe("n=1"); expect(screen.getByText("bare=1")).toBeTruthy(); act(() => screen.getByRole("button").click()); expect(screen.getByRole("button").textContent).toBe("n=2"); expect(screen.getByText("bare=2")).toBeTruthy(); }); });