## TL;DR

React warns when a test lets state update outside `act`, because the test then asserts on a half-updated tree. Wrap the render and the triggering event in `act`, use the async form and await it for effects that fetch, and the warning goes away.

## Error

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

When testing, code that causes React state updates should be wrapped into act(...):

act(function() {
  /* fire events that update state */
});
/* assert on the output */
```

## Steps

1. Find the call the warning points at: the render, fireEvent, or userEvent call that triggers the update. Expected: you can name the offending call.
2. Wrap it in act. Expected: the warning moves or disappears for that call.
```js
act(function () {
  render(React.createElement(MyComponent))
})
```
3. If the update is async (a fetch inside useEffect), use the async form and await it. Expected: no warning, and effects settle before your assertions run.
```js
await act(async function () {
  render(React.createElement(MyComponent))
})
```
4. Set `globalThis.IS_REACT_ACT_ENVIRONMENT = true` in your test setup file (React 18 requires it). Expected: act stops warning that the test environment is not configured.
5. Rerun the suite. Expected: zero act warnings in the output.

## When to use

- The warning names one of your components in a test run.
- The warning appeared after the component gained async data fetching.
- Upgrading to React 18 surfaced a batch of new warnings.

## When not to use

- The warning appears in a real browser console, not a test; fix the app code instead.
- You use React Testing Library's render, fireEvent, and waitFor, which already wrap in act; the warning means you did something outside those helpers.
- The code under test is not React.

## Tool compatibility

- React 16.8 through 18 (React.act in 18.3 and 19).
- jest, Vitest, and React Testing Library (its helpers wrap act for you).

## Variant phrasings

### not wrapped in act(...) after fireEvent

The event triggered a state update outside act. Wrap the fireEvent call itself, not just the render.

### When testing, code that causes React state updates should be wrapped into act(...)

The advisory half of the same warning. It always accompanies the "not wrapped" line and needs the same fix.

## Why it happens

React batches and flushes updates on its own schedule. `act` tells React to drain every effect and update synchronously, so assertions run against the final tree instead of a mid-update one.

## Edge cases

- Awaiting a promise inside act that never resolves hangs the test; make sure the async work completes.
- userEvent v14 is async and must be awaited, or its updates land outside act.
- Fake timers need advancing inside act too, or timer-driven updates trigger the warning.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_VKQMFOZU-XE0LJX5t9JYgA
