act

김동현·2026년 3월 17일

act

소개

act는 단언(assertion)을 하기 전에 대기 중인 React 업데이트를 적용할 수 있게 해주는 테스트 헬퍼예요.

await act(async actFn)

컴포넌트를 단언할 준비를 하려면, 컴포넌트를 렌더링하고 업데이트를 수행하는 코드를 await act() 호출 안에 감싸주면 돼요. 이렇게 하면 테스트가 브라우저에서 React가 실제로 동작하는 방식과 더 가깝게 실행돼요.

참고

act()를 직접 사용하는 건 좀 장황하게 느껴질 수 있어요. 보일러플레이트 코드를 줄이려면 React Testing Library 같은 라이브러리를 사용할 수 있는데, 이 라이브러리의 헬퍼들은 내부적으로 act()로 감싸져 있어요.


목차


레퍼런스

await act(async actFn)

UI 테스트를 작성할 때, 렌더링, 사용자 이벤트, 데이터 패칭 같은 작업들은 사용자 인터페이스와의 상호작용 "단위"로 볼 수 있어요. React는 act()라는 헬퍼를 제공하는데, 이건 이런 "단위"와 관련된 모든 업데이트가 처리되고 DOM에 적용된 후에 단언을 할 수 있도록 보장해줘요.

act라는 이름은 Arrange-Act-Assert 패턴에서 따온 거예요. 이 패턴은 테스트를 "준비(Arrange) - 실행(Act) - 검증(Assert)"의 세 단계로 나누는 방법론인데, act는 그 중 "실행" 단계에 해당한다고 보면 돼요.

it ('renders with button disabled', async () => {
  await act(async () => {
    root.render(<TestComponent />)
  });
  expect(container.querySelector('button')).toBeDisabled();
});

참고

actawaitasync 함수와 함께 사용하는 것을 권장해요. 동기(sync) 버전도 많은 경우에 동작하긴 하지만, 모든 경우에 동작하지는 않아요. 그리고 React가 내부적으로 업데이트를 스케줄링하는 방식 때문에, 동기 버전을 언제 사용할 수 있는지 예측하기 어려워요.

앞으로 동기 버전은 deprecated(사용 중단 예정)으로 표시하고 제거할 계획이에요.

매개변수

  • async actFn: 테스트 중인 컴포넌트의 렌더링이나 상호작용을 감싸는 비동기 함수예요. actFn 안에서 트리거된 모든 업데이트는 내부 act 큐에 추가되고, 이것들이 한꺼번에 플러시(flush)되어 변경 사항이 처리되고 DOM에 적용돼요. 비동기이기 때문에, React는 비동기 경계를 넘는 코드도 실행하고, 스케줄된 업데이트도 플러시해줘요.

반환값

act는 아무것도 반환하지 않아요.

사용법

컴포넌트를 테스트할 때, act를 사용해서 출력에 대한 단언을 할 수 있어요.

예를 들어, 아래와 같은 Counter 컴포넌트가 있다고 해볼게요. 아래의 사용 예시들은 이 컴포넌트를 어떻게 테스트하는지 보여줘요:

// Counter.js
function Counter() {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount(prev => prev + 1);
  }

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={handleClick}>
        Click me
      </button>
    </div>
  )
}

테스트에서 컴포넌트 렌더링하기

컴포넌트의 렌더링 출력을 테스트하려면, 렌더링을 act() 안에 감싸주면 돼요:

import {act} from 'react';
import ReactDOMClient from 'react-dom/client';
import Counter from './Counter';

it('can render and update a counter', async () => {
  container = document.createElement('div');
  document.body.appendChild(container);
  
  // ✅ act() 안에서 컴포넌트를 렌더링해요.
  await act(() => {
    ReactDOMClient.createRoot(container).render(<Counter />);
  });
  
  const button = container.querySelector('button');
  const label = container.querySelector('p');
  expect(label.textContent).toBe('You clicked 0 times');
  expect(document.title).toBe('You clicked 0 times');
});

여기서 컨테이너를 만들고, document에 추가한 다음, act() 안에서 Counter 컴포넌트를 렌더링하고 있어요. 이렇게 하면 컴포넌트가 렌더링되고 이펙트(effect)가 적용된 후에 단언을 할 수 있어요.

act를 사용하면 모든 업데이트가 적용된 후에 단언을 하게 되므로, 테스트 결과를 신뢰할 수 있게 돼요.

테스트에서 이벤트 디스패치하기

이벤트를 테스트하려면, 이벤트 디스패치를 act() 안에 감싸주면 돼요:

import {act} from 'react';
import ReactDOMClient from 'react-dom/client';
import Counter from './Counter';

it.only('can render and update a counter', async () => {
  const container = document.createElement('div');
  document.body.appendChild(container);
  
  await act( async () => {
    ReactDOMClient.createRoot(container).render(<Counter />);
  });
  
  // ✅ act() 안에서 이벤트를 디스패치해요.
  await act(async () => {
    button.dispatchEvent(new MouseEvent('click', { bubbles: true }));
  });

  const button = container.querySelector('button');
  const label = container.querySelector('p');
  expect(label.textContent).toBe('You clicked 1 times');
  expect(document.title).toBe('You clicked 1 times');
});

여기서 act로 컴포넌트를 렌더링하고, 그 다음 또 다른 act() 안에서 이벤트를 디스패치하고 있어요. 이렇게 하면 이벤트로 인한 모든 업데이트가 적용된 후에 단언을 할 수 있어요.

주의

DOM 이벤트를 디스패치하는 건 DOM 컨테이너가 document에 추가되어 있을 때만 동작한다는 걸 잊지 마세요. 보일러플레이트 코드를 줄이려면 React Testing Library 같은 라이브러리를 사용할 수 있어요.

문제 해결

"The current testing environment is not configured to support act(...)" 에러가 발생해요

act를 사용하려면 테스트 환경에서 global.IS_REACT_ACT_ENVIRONMENT=true를 설정해야 해요. 이건 act가 올바른 환경에서만 사용되도록 보장하기 위한 거예요.

이 전역 설정을 하지 않으면, 다음과 같은 에러를 보게 될 거예요:

⛔ Warning: The current testing environment is not configured to support act(...)

이 문제를 해결하려면, React 테스트를 위한 전역 설정 파일에 아래 코드를 추가해주세요:

global.IS_REACT_ACT_ENVIRONMENT=true

참고

React Testing Library 같은 테스트 프레임워크에서는 IS_REACT_ACT_ENVIRONMENT가 이미 설정되어 있어요. 그래서 별도로 설정할 필요가 없죠.


사이트맵

모든 문서 페이지 개요

profile
프론트에_가까운_풀스택_개발자

0개의 댓글