component has used useState to count and display a warning under certain conditions.
Look at its code again: JSX for the screen and logic for the calculation are mixed together.
What if another page needs the same counting behavior?
Should we copy and paste it?
This is where a
custom hook
helps.
Today we will separate the brain, the hook, from the body, the component, and test that brain independently.
Step 1: Extracting the logic through refactoring ๐
Create src/hooks and move the component's logic into useCounter.ts.
This is a
refactoring
step: We change the internal structure without changing the tests.
Step 2: Testing the hook with renderHook and act ๐
Now test whether the extracted useCounter works correctly.
A hook is not a component, so we cannot use render(<useCounter />).
We need renderHook and act.
renderHook
Creates a test component and runs the hook inside it.
act
Tells
React
that an important state-changing operation is about to happen, such as a simulated click.
The logs show that calling increment inside act changes result.current.count from 0 to 1.
Notice that the existing Counter.test.tsx also still
passes
.
We changed the implementation from useState inside the component to a custom hook, but the screen and behavior seen by users remain unchanged, so the original tests keep working.