# When to Use act in React Testing Library with Jest: A Complete Guide

> Learn when to use act in React Testing Library with Jest. Wrap state updates and effects with act() for stable DOM and reliable tests. Avoid warnings and flaky test outcomes.

- Repository: [Jest/jest](https://github.com/jestjs/jest)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Wrap any code that triggers React state updates, effects, or re-renders with `act()` to ensure the DOM is stable before assertions, preventing "state update not wrapped in act" warnings and flaky tests.**

The `act` utility is essential for writing reliable unit tests in React DOM applications using Jest. When testing components in the `jestjs/jest` ecosystem alongside React Testing Library, understanding when to explicitly wrap code with **act in React Testing Library** prevents asynchronous state warnings and ensures your assertions run against a fully updated DOM.

## What Is act in React Testing Library?

The `act` function is a testing utility that guarantees all **React updates**—including state changes, prop updates, and effect executions—are flushed before you make any assertions. According to the Jest documentation in [`website/versioned_docs/version-30.0/TutorialReact.md`](https://github.com/jestjs/jest/blob/main/website/versioned_docs/version-30.0/TutorialReact.md), `act` ensures that the component is in a stable state when you read the DOM or capture snapshots.

When you wrap code with `act`, React processes all pending work synchronously, preventing the common warning: "An update to Component inside a test was not wrapped in act."

## When Should You Wrap Code with act?

Understanding when to explicitly use **act in React Testing Library** depends on what triggers the React update. While React Testing Library automatically wraps many utilities like `fireEvent` and `render` with `act`, certain scenarios require manual intervention.

### Synchronous State Updates

For standard user interactions using React Testing Library's event utilities, you typically do not need additional `act` wrappers. The `fireEvent` method in [`examples/react-testing-library/__tests__/CheckboxWithLabel-test.js`](https://github.com/jestjs/jest/blob/main/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js) is already wrapped internally. However, if you call a component method directly that triggers `setState`, you must wrap it with `act`.

### Asynchronous Operations and Promises

Any code that involves `await`, `Promise` resolution, or async state updates requires `await act(async () => { ... })`. This pattern ensures that all effects and state updates triggered by the promise resolution are flushed before assertions run.

### Timer-Based Updates

When testing components that use `setTimeout`, `setInterval`, or `requestAnimationFrame`, wrap timer advancements with `act`. This is critical when using Jest's fake timers to ensure React processes the timer callbacks correctly.

### Direct Component Method Calls

If your test calls methods directly on a component instance or ref that update state—rather than simulating DOM events—you must wrap these calls with `act`. This pattern appears when testing legacy components or imperative handles, though React Testing Library favors user-centric testing that typically avoids this approach.

## Practical Code Examples

The following examples demonstrate proper usage of **act in React Testing Library** based on patterns found in the `jestjs/jest` repository.

### Example 1: Standard Event Handling (No Extra act Needed)

React Testing Library automatically wraps `fireEvent` with `act`. This example from [`examples/react-testing-library/__tests__/CheckboxWithLabel-test.js`](https://github.com/jestjs/jest/blob/main/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js) shows a typical pattern:

```javascript
import {render, fireEvent} from '@testing-library/react';
import CheckboxWithLabel from '../CheckboxWithLabel';

test('checkbox toggles when clicked', () => {
  const {getByLabelText} = render(<CheckboxWithLabel label="Accept" />);

  const checkbox = getByLabelText(/accept/i);
  expect(checkbox).not.toBeChecked();

  fireEvent.click(checkbox); // RTL internally wraps this in act
  expect(checkbox).toBeChecked();
});

```

### Example 2: Direct Component Method Calls

When calling component methods directly that trigger state updates, explicitly wrap with `act`:

```javascript
import {act, render} from '@testing-library/react';
import Counter from '../Counter';

test('counter increments via method call', () => {
  const {container, getByText} = render(<Counter />);

  // Counter exposes an increment method (not a DOM event)
  act(() => {
    container.firstChild.increment(); // triggers setState
  });

  expect(getByText(/count: 1/i)).toBeInTheDocument();
});

```

### Example 3: Asynchronous State Updates

For async operations, use `await act(async () => { ... })` to ensure promises resolve before assertions:

```javascript
import {act, render, screen, waitFor} from '@testing-library/react';
import AsyncButton from '../AsyncButton';

test('button shows loading then result', async () => {
  render(<AsyncButton />);

  fireEvent.click(screen.getByRole('button', {name: /load/i}));

  // Wait for the async state change
  await act(async () => {
    await waitFor(() => expect(screen.getByText(/done/i)).toBeInTheDocument());
  });
});

```

### Example 4: Timer-Based Updates with Fake Timers

When testing components with timers, wrap timer advancements with `act`:

```javascript
import {act, render, screen} from '@testing-library/react';
import TimerComponent from '../TimerComponent';

jest.useFakeTimers();

test('timer updates after 1 second', () => {
  render(<TimerComponent />);

  act(() => {
    jest.advanceTimersByTime(1000); // triggers setTimeout inside component
  });

  expect(screen.getByText(/elapsed: 1s/i)).toBeInTheDocument();
});

```

## Implementation Details in the Jest Repository

Understanding how **act in React Testing Library** integrates with Jest requires examining specific files in the `jestjs/jest` repository.

The official Jest tutorial documents `renderer.act` usage for snapshot testing in [`website/versioned_docs/version-30.0/TutorialReact.md`](https://github.com/jestjs/jest/blob/main/website/versioned_docs/version-30.0/TutorialReact.md) (lines 106-114). This demonstrates the canonical pattern for wrapping React updates in act when using the React test renderer directly.

For React Testing Library specifically, the reference implementation appears in [`examples/react-testing-library/__tests__/CheckboxWithLabel-test.js`](https://github.com/jestjs/jest/blob/main/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js). This file illustrates how RTL automatically handles `act` wrapping for `fireEvent` calls, serving as the practical baseline for most DOM testing scenarios.

The core test execution environment that surfaces `act` warnings is managed by [`packages/jest-runner/src/runTest.ts`](https://github.com/jestjs/jest/blob/main/packages/jest-runner/src/runTest.ts). This runner executes test files and captures console warnings, including React's "not wrapped in act" notifications.

While React Testing Library provides its own `act` export (re-exported from React DOM), the underlying implementation in the React test renderer resides in [`packages/react-test-renderer/src/renderer.ts`](https://github.com/jestjs/jest/blob/main/packages/react-test-renderer/src/renderer.ts). This file provides the `act` function that ensures all React work is flushed before continuing.

For broader context on testing framework integration, [`website/versioned_docs/version-30.0/TestingFrameworks.md`](https://github.com/jestjs/jest/blob/main/website/versioned_docs/version-30.0/TestingFrameworks.md) lists recommended testing frameworks (including React Testing Library) and links to official documentation discussing `act` usage patterns.

## Summary

- **Wrap synchronous state updates** with `act` when calling component methods directly, though React Testing Library automatically wraps `fireEvent` and `render` calls.
- **Use `await act(async () => { ... })`** for any asynchronous operations, promise resolutions, or async state changes to ensure effects complete before assertions.
- **Always wrap timer advancements** with `act` when using `jest.advanceTimersByTime` or similar timer mocks to trigger React updates correctly.
- **Reference canonical examples** in [`website/versioned_docs/version-30.0/TutorialReact.md`](https://github.com/jestjs/jest/blob/main/website/versioned_docs/version-30.0/TutorialReact.md) and [`examples/react-testing-library/__tests__/CheckboxWithLabel-test.js`](https://github.com/jestjs/jest/blob/main/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js) for implementation patterns.
- **Prevent warnings** by ensuring all React work is flushed, eliminating "state update not wrapped in act" console noise in [`packages/jest-runner/src/runTest.ts`](https://github.com/jestjs/jest/blob/main/packages/jest-runner/src/runTest.ts) execution environments.

## Frequently Asked Questions

### When do I need to manually wrap code with act in React Testing Library?

You need to manually wrap code with `act` when performing actions that React Testing Library does not automatically handle. While `render` and `fireEvent` are already wrapped internally, you must use `act` when calling component methods directly via refs or instances, advancing Jest fake timers, or resolving asynchronous promises that trigger state updates. According to the Jest repository's [`examples/react-testing-library/__tests__/CheckboxWithLabel-test.js`](https://github.com/jestjs/jest/blob/main/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js), standard DOM events require no manual wrapping, but direct state mutations do.

### Why does React warn about updates not being wrapped in act?

React issues this warning when state updates, effect executions, or re-renders occur outside of an `act` context during test execution. The warning surfaces through the test runner defined in [`packages/jest-runner/src/runTest.ts`](https://github.com/jestjs/jest/blob/main/packages/jest-runner/src/runTest.ts) to alert developers that assertions might run against stale DOM states. Wrapping updates with `act` ensures React flushes all pending work synchronously, making tests deterministic and eliminating console noise.

### Should I use act with React Testing Library's render and fireEvent?

No, you generally should not wrap `render` or `fireEvent` calls with additional `act` blocks because React Testing Library already wraps these utilities internally. The source code in [`website/versioned_docs/version-30.0/TutorialReact.md`](https://github.com/jestjs/jest/blob/main/website/versioned_docs/version-30.0/TutorialReact.md) demonstrates that `renderer.act` is used internally by the testing framework. However, if you are using the React test renderer directly or calling methods on component instances, you must explicitly use `act` from `react-test-renderer` or `@testing-library/react`.

### How do I test asynchronous updates with act in Jest?

For asynchronous operations, use the async variant: `await act(async () => { ... })`. This pattern ensures that promises resolve and all resulting state updates and effects complete before the test continues. As shown in the Jest repository examples, you should wrap `waitFor` calls or direct promise resolutions inside the async `act` block when testing components that fetch data or use `setTimeout`. This prevents race conditions and ensures the DOM reflects the final state when assertions run.