Ad Space — Top Banner

Warning: An update to ... inside a test was not wrapped in act(...)

React JavaScript Framework

Severity: Minor

What Does This Error Mean?

The act() warning appears in tests when your code causes a React state update outside of React's expected test flow. React needs all updates (state changes, effects, user events) to be wrapped in act() so it can flush them before you make assertions. Without act(), your test may assert on stale state — the state before the update — giving you false results.

Affected Models

  • React 16.8 and later
  • All React testing with Jest, React Testing Library, or Enzyme

Common Causes

  • An async operation in a test (like a fetch mock or setTimeout) completes and updates state, but the test did not await the update
  • Simulating a user event without wrapping it in act() or using the userEvent helpers from React Testing Library
  • Using setState in a test directly rather than triggering it through user interaction
  • Not awaiting async effects — a useEffect that makes an API call updates state, but the test moves on before the effect finishes
  • Using React Testing Library's fireEvent instead of userEvent, which does not automatically wrap in act()

How to Fix It

  1. If you are using React Testing Library (which is recommended), switch from fireEvent to userEvent. The userEvent library wraps everything in act() automatically.

    Install: npm install @testing-library/user-event. Then: const user = userEvent.setup(); await user.click(button); — no manual act() needed.

  2. For async operations, use waitFor() from React Testing Library. It polls until your assertion passes, automatically waiting for all state updates to settle.

    Example: await waitFor(() => expect(screen.getByText('Loaded')).toBeInTheDocument()); — this waits for the async update before checking.

  3. If you must use act() manually for async code, use the async form: await act(async () => { ... your async code ... }); — this flushes all pending state updates and effects.

    Example: await act(async () => { render(<MyComponent />); await fetchMock.flush(); });

  4. Mock timers with Jest's fake timers to control setTimeout and setInterval in tests. Then advance time manually inside act() to trigger timer callbacks at the right moment.

    Example: jest.useFakeTimers(); act(() => { jest.advanceTimersByTime(1000); }); — this fires any timers that would have run after 1 second.

  5. For tests using React 18, the @testing-library/react version 13+ already wraps render() in act() by default. Ensure your testing library is up to date before troubleshooting further.

    Run: npm list @testing-library/react — check you are on version 13 or later for React 18 compatibility.

When to Call a Professional

The act() warning is purely a test code issue — it never affects your production app. Fix it by using the correct async testing patterns and the right testing library helpers.

Frequently Asked Questions

Does the act() warning affect my users?

No. The act() warning only appears in test environments — it never shows in production or development mode outside of tests. Your app works correctly for users. The warning matters because it means your tests might be making assertions on stale state, which could lead to tests that pass incorrectly — false positives. Fix it to make your tests reliable, not to fix a user-facing bug.

Why does the warning mention a component name like 'An update to Counter inside a test'?

React identifies which component had an unwrapped update. The component name in the warning is where setState was called outside of act(). This tells you which component's update you need to wrap — trace back from that component to find the async operation or timer that triggered the update.

Should I just suppress the act() warning to make it go away?

No. Suppressing warnings with jest.spyOn(console, 'error') hides the symptom without fixing the cause. Your tests will still be unreliable — they will just be unreliable silently. The correct fix is to await all async updates using waitFor() or the async act() form. Treating the warning as a real problem that needs fixing leads to better, more reliable tests.