web/react

act

dev_been94 2024. 12. 16. 11:28
728x90
λ°˜μ‘ν˜•

act

 

🎯 actλž€ λ¬΄μ—‡μΈκ°€μš”?

**act**λŠ” Reactμ—μ„œ ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•  λ•Œ μƒνƒœ λ³€ν™”λ‚˜ ν™”λ©΄ μ—…λ°μ΄νŠΈκ°€ λͺ¨λ‘ μ™„λ£Œλœ μ‹œμ μ„ 보μž₯ν•΄μ£ΌλŠ” ν•¨μˆ˜μ˜ˆμš”.
μ‰½κ²Œ λ§ν•˜λ©΄ **"ν™”λ©΄ μ—…λ°μ΄νŠΈκ°€ λ‹€ λλ‚œ 후에 ν™•μΈν•˜κ²Œ ν•΄μ£ΌλŠ” 도ꡬ"**라고 μƒκ°ν•˜λ©΄ λΌμš”.

ReactλŠ” μƒνƒœκ°€ λ°”λ€” λ•Œλ§ˆλ‹€ 화면이 μ—…λ°μ΄νŠΈλ˜μ£ ?
그런데 ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•  λ•Œ 화면이 μ™„μ „νžˆ μ—…λ°μ΄νŠΈλ˜κΈ° 전에 ν™•μΈν•˜λ©΄, ν…ŒμŠ€νŠΈκ°€ μ‹€νŒ¨ν•  수 μžˆμ–΄μš”.
이럴 λ•Œ **act**λ₯Ό μ‚¬μš©ν•˜λ©΄ ν™”λ©΄ μ—…λ°μ΄νŠΈκ°€ μ™„λ£Œλ  λ•ŒκΉŒμ§€ κΈ°λ‹€λ €μ€˜μ„œ μ•ˆμ •μ μΈ ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•  수 μžˆλ‹΅λ‹ˆλ‹€.

 

🧩 μ™œ actκ°€ ν•„μš”ν• κΉŒμš”?

상상해 λ³΄μ„Έμš”.

μ—¬λŸ¬λΆ„μ΄ ν”Όμž κ°€κ²Œλ₯Ό μš΄μ˜ν•˜κ³  μžˆμ–΄μš”. πŸ•

  • 주문을 λ°›μœΌλ©΄ ν”Όμžλ₯Ό λ§Œλ“€κΈ° μ‹œμž‘ν•©λ‹ˆλ‹€.
  • ν”Όμžκ°€ μ™„μ „νžˆ κ΅¬μ›Œμ§€κΈ° 전에 μ†λ‹˜μ—κ²Œ 보여쀀닀면?
    μ†λ‹˜μ€ "이게 뭐야? 덜 μ΅μ—ˆλ„€!"라고 ν•  κ±°μ˜ˆμš”.

React ν…ŒμŠ€νŠΈλ„ λ§ˆμ°¬κ°€μ§€μ˜ˆμš”.
화면이 λ‹€ μ—…λ°μ΄νŠΈλ˜κΈ° 전에 μƒνƒœλ₯Ό ν™•μΈν•˜λ©΄ 잘λͺ»λœ κ²°κ³Όκ°€ λ‚˜μ˜¬ 수 μžˆμ–΄μš”.
κ·Έλž˜μ„œ actλŠ” ν”Όμžκ°€ μ™„μ „νžˆ κ΅¬μ›Œμ§ˆ λ•ŒκΉŒμ§€ 기닀렀주듯이 React μ»΄ν¬λ„ŒνŠΈμ˜ μƒνƒœμ™€ ν™”λ©΄ μ—…λ°μ΄νŠΈκ°€ λ‹€ λλ‚œ ν›„μ—λ§Œ ν…ŒμŠ€νŠΈλ₯Ό μ§„ν–‰ν•˜κ²Œ ν•΄μ€˜μš”.

 

πŸ› οΈ actλ₯Ό μ‚¬μš©ν•˜λŠ” 예제

κ°„λ‹¨ν•œ λ²„νŠΌ 클릭 μ‹œ μΉ΄μš΄ν„°κ°€ μ¦κ°€ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈλ₯Ό ν…ŒμŠ€νŠΈν•΄λ³Όκ²Œμš”.

 

1. μ»΄ν¬λ„ŒνŠΈ μ½”λ“œ

import React, { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>카운트: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1 증가</button>
    </div>
  );
}

 

2. ν…ŒμŠ€νŠΈ μ½”λ“œ (act μ‚¬μš©)

actλ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©΄ μƒνƒœ μ—…λ°μ΄νŠΈκ°€ μ™„λ£Œλ˜κΈ° 전에 ν…ŒμŠ€νŠΈκ°€ 싀행될 수 μžˆμ–΄μš”.
이럴 땐 act둜 κ°μ‹Έμ„œ μ—…λ°μ΄νŠΈκ°€ μ™„λ£Œλœ ν›„ ν™•μΈν•˜λ„λ‘ ν•΄μ•Ό ν•΄μš”.

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

test('λ²„νŠΌ 클릭 μ‹œ μΉ΄μš΄ν„°κ°€ 증가해야 ν•œλ‹€', () => {
  render(<Counter />);

  const button = screen.getByText('+1 증가');
  const counter = screen.getByText(/카운트: 0/);

  // actλ₯Ό μ‚¬μš©ν•΄μ„œ μƒνƒœ μ—…λ°μ΄νŠΈκ°€ μ™„λ£Œλ˜λ„λ‘ κΈ°λ‹€λ¦Ό
  act(() => {
    fireEvent.click(button);
  });

  // μ—…λ°μ΄νŠΈλœ 값을 확인
  expect(screen.getByText(/카운트: 1/)).toBeInTheDocument();
});

 

πŸ” μ½”λ“œ μ„€λͺ…

  1. render
    • ν…ŒμŠ€νŠΈ 도ꡬ인 **@testing-library/react**λ₯Ό μ‚¬μš©ν•΄ μ»΄ν¬λ„ŒνŠΈλ₯Ό 화면에 λ Œλ”λ§ν•©λ‹ˆλ‹€.
  2. act μ‚¬μš©
    • act둜 **fireEvent.click(button)**을 감싸면 λ²„νŠΌ 클릭으둜 μΈν•œ μƒνƒœ 변화와 ν™”λ©΄ μ—…λ°μ΄νŠΈκ°€ μ™„λ£Œλ  λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦½λ‹ˆλ‹€.
  3. μ—…λ°μ΄νŠΈλœ κ°’ 확인
    • μƒνƒœκ°€ μ—…λ°μ΄νŠΈλœ ν›„, 화면에 **"카운트: 1"**이 μžˆλŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€.

 

🚨 actλ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©΄?

λ§Œμ•½ actλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•˜λ©΄ 이런 κ²½κ³ κ°€ λ‚˜μ˜¬ 수 μžˆμ–΄μš”:

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

이 κ²½κ³ λŠ” Reactκ°€ μƒνƒœ 변화와 ν™”λ©΄ μ—…λ°μ΄νŠΈκ°€ μ™„λ£Œλ˜μ§€ μ•Šμ•˜μ„ 수 μžˆλ‹€κ³  μ•Œλ €μ£ΌλŠ” κ±°μ˜ˆμš”.
ν…ŒμŠ€νŠΈμ—μ„œ 이런 λΆˆμ•ˆμ •ν•œ 상황을 ν”Όν•˜λ €λ©΄ actλ₯Ό κΌ­ μ‚¬μš©ν•΄μ•Ό ν•΄μš”.

 

🌟 act μ‚¬μš© μ‹œ μ£Όμ˜ν•  점

  1. μƒνƒœ μ—…λ°μ΄νŠΈλ₯Ό 감싸기
    • μƒνƒœλ‚˜ ν™”λ©΄ μ—…λ°μ΄νŠΈλ₯Ό ν…ŒμŠ€νŠΈν•  λ•ŒλŠ” act둜 κ°μ‹Έμ£Όμ„Έμš”.
  2. 비동기 μž‘μ—… 처리
    • 비동기 μ½”λ“œ(예: setTimeout, API 호좜)μ—μ„œ μƒνƒœλ₯Ό μ—…λ°μ΄νŠΈν•  λ•ŒλŠ” **await act(async () => {...})**λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•΄μš”.
      await act(async () => {
        await fetchData(); // 비동기 μž‘μ—… μ™„λ£Œ λŒ€κΈ°
      });
  3. ν…ŒμŠ€νŠΈ 도ꡬ
    • **@testing-library/react**와 ν•¨κ»˜ μ‚¬μš©ν•  λ•Œ actλŠ” λŒ€λΆ€λΆ„ μžλ™μœΌλ‘œ μ μš©λ©λ‹ˆλ‹€.
    • ν•˜μ§€λ§Œ λͺ…μ‹œμ μœΌλ‘œ μ‚¬μš©ν•΄μ•Ό ν•  λ•Œλ„ μžˆμœΌλ‹ˆ κ²½κ³ κ°€ 뜨면 확인해 λ³΄μ„Έμš”.

πŸš€ ν•œ 쀄 μš”μ•½

actλŠ” React ν…ŒμŠ€νŠΈμ—μ„œ μƒνƒœ μ—…λ°μ΄νŠΈμ™€ ν™”λ©΄ λ Œλ”λ§μ΄ μ™„λ£Œλœ ν›„μ—λ§Œ ν…ŒμŠ€νŠΈκ°€ μ§„ν–‰λ˜λ„λ‘ λ„μ™€μ£ΌλŠ” ν•¨μˆ˜μ˜ˆμš”.
ν…ŒμŠ€νŠΈκ°€ 더 μ •ν™•ν•˜κ³  μ•ˆμ •μ μœΌλ‘œ μž‘λ™ν•˜λ„λ‘ κΌ­ μ‚¬μš©ν•΄ μ£Όμ„Έμš”!

 

 

728x90
λ°˜μ‘ν˜•