javascript / intermediate
Snippet
Testing Controlled Hook State Reductions Using renderHook and act
Custom React hooks encapsulate stateful control flow that must be validated in isolation. Using renderHook mounts the hook in an ephemeral test container, while wrapping trigger functions in act ensures all asynchronous state batches and DOM side effects settle before assertions run.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { renderHook, act } from '@testing-library/react';import { useState, useCallback } from 'react';function useBoundedStepCounter(min, max, initial = 0) {const [count, setCount] = useState(initial);const increment = useCallback(() => {setCount((curr) => (curr < max ? curr + 1 : curr));}, [max]);return { count, increment };}describe('useBoundedStepCounter', () => {it('does not increment count beyond maximum boundary', () => {const { result } = renderHook(() => useBoundedStepCounter(0, 2, 1));act(() => {result.current.increment();result.current.increment();});expect(result.current.count).toBe(2);});});
react
Breakdown
1
setCount((curr) => (curr < max ? curr + 1 : curr));
Applies boundary control logic to prevent state values from exceeding the maximum limit.
2
const { result } = renderHook(() => useBoundedStepCounter(0, 2, 1));
Mounts the hook in a virtual testing component and exposes a mutable result ref.
3
act(() => { result.current.increment(); });
Dispatches hook state actions within the act boundary to flush all pending React state updates.