act is a test helper to apply pending React updates before making assertions.
awaitact(asyncactFn)To prepare a component for assertions, wrap the code rendering it and performing updates inside anawait act() call. This makes your test run closer to how React works in the browser.
Note
You might find usingact() directly a bit too verbose. To avoid some of the boilerplate, you could use a library likeReact Testing Library, whose helpers are wrapped withact().
Reference
await act(async actFn)
When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface. React provides a helper calledact() that makes sure all updates related to these “units” have been processed and applied to the DOM before you make any assertions.
The nameact comes from theArrange-Act-Assert pattern.
it('renders with button disabled',async()=>{
awaitact(async()=>{
root.render(<TestComponent/>)
});
expect(container.querySelector('button')).toBeDisabled();
});Note
We recommend usingact withawait and anasync function. Although the sync version works in many cases, it doesn’t work in all cases and due to the way React schedules updates internally, it’s difficult to predict when you can use the sync version.
We will deprecate and remove the sync version in the future.
Parameters
async actFn: An async function wrapping renders or interactions for components being tested. Any updates triggered within theactFn, are added to an internal act queue, which are then flushed together to process and apply any changes to the DOM. Since it is async, React will also run any code that crosses an async boundary, and flush any updates scheduled.
Returns
act does not return anything.
Usage
When testing a component, you can useact to make assertions about its output.
For example, let’s say we have thisCounter component, the usage examples below show how to test it:
functionCounter(){
const[count,setCount] =useState(0);
consthandleClick =()=>{
setCount(prev=>prev +1);
}
useEffect(()=>{
document.title =`You clicked${count} times`;
},[count]);
return(
<div>
<p>You clicked{count} times</p>
<buttononClick={handleClick}>
Click me
</button>
</div>
)
}Rendering components in tests
To test the render output of a component, wrap the render insideact():
import{act}from'react';
importReactDOMClientfrom'react-dom/client';
importCounterfrom'./Counter';
it('can render and update a counter',async()=>{
container =document.createElement('div');
document.body.appendChild(container);
// ✅ Render the component inside act().
awaitact(()=>{
ReactDOMClient.createRoot(container).render(<Counter/>);
});
constbutton =container.querySelector('button');
constlabel =container.querySelector('p');
expect(label.textContent).toBe('You clicked 0 times');
expect(document.title).toBe('You clicked 0 times');
});Here, we create a container, append it to the document, and render theCounter component insideact(). This ensures that the component is rendered and its effects are applied before making assertions.
Usingact ensures that all updates have been applied before we make assertions.
Dispatching events in tests
To test events, wrap the event dispatch insideact():
import{act}from'react';
importReactDOMClientfrom'react-dom/client';
importCounterfrom'./Counter';
it.only('can render and update a counter',async()=>{
constcontainer =document.createElement('div');
document.body.appendChild(container);
awaitact(async()=>{
ReactDOMClient.createRoot(container).render(<Counter/>);
});
// ✅ Dispatch the event inside act().
awaitact(async()=>{
button.dispatchEvent(newMouseEvent('click',{bubbles:true}));
});
constbutton =container.querySelector('button');
constlabel =container.querySelector('p');
expect(label.textContent).toBe('You clicked 1 times');
expect(document.title).toBe('You clicked 1 times');
});Here, we render the component withact, and then dispatch the event inside anotheract(). This ensures that all updates from the event are applied before making assertions.
Pitfall
Don’t forget that dispatching DOM events only works when the DOM container is added to the document. You can use a library likeReact Testing Library to reduce the boilerplate code.
Troubleshooting
I’m getting an error: “The current testing environment is not configured to support act(…)”
Usingact requires settingglobal.IS_REACT_ACT_ENVIRONMENT=true in your test environment. This is to ensure thatact is only used in the correct environment.
If you don’t set the global, you will see an error like this:
To fix, add this to your global setup file for React tests:
global.IS_REACT_ACT_ENVIRONMENT=trueNote
In testing frameworks likeReact Testing Library,IS_REACT_ACT_ENVIRONMENT is already set for you.