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();
});
π μ½λ μ€λͺ
- render
- ν μ€νΈ λκ΅¬μΈ **@testing-library/react**λ₯Ό μ¬μ©ν΄ μ»΄ν¬λνΈλ₯Ό νλ©΄μ λ λλ§ν©λλ€.
- act μ¬μ©
- actλ‘ **fireEvent.click(button)**μ κ°μΈλ©΄ λ²νΌ ν΄λ¦μΌλ‘ μΈν μν λ³νμ νλ©΄ μ λ°μ΄νΈκ° μλ£λ λκΉμ§ κΈ°λ€λ¦½λλ€.
- μ
λ°μ΄νΈλ κ° νμΈ
- μνκ° μ λ°μ΄νΈλ ν, νλ©΄μ **"μΉ΄μ΄νΈ: 1"**μ΄ μλμ§ νμΈν©λλ€.
π¨ actλ₯Ό μ¬μ©νμ§ μμΌλ©΄?
λ§μ½ actλ₯Ό μ¬μ©νμ§ μκ³ ν μ€νΈλ₯Ό μμ±νλ©΄ μ΄λ° κ²½κ³ κ° λμ¬ μ μμ΄μ:
Warning: An update to Counter inside a test was not wrapped in act(...).
μ΄ κ²½κ³ λ Reactκ° μν λ³νμ νλ©΄ μ
λ°μ΄νΈκ° μλ£λμ§ μμμ μ μλ€κ³ μλ €μ£Όλ κ±°μμ.
ν
μ€νΈμμ μ΄λ° λΆμμ ν μν©μ νΌνλ €λ©΄ actλ₯Ό κΌ μ¬μ©ν΄μΌ ν΄μ.
π act μ¬μ© μ μ£Όμν μ
- μν μ
λ°μ΄νΈλ₯Ό κ°μΈκΈ°
- μνλ νλ©΄ μ λ°μ΄νΈλ₯Ό ν μ€νΈν λλ actλ‘ κ°μΈμ£ΌμΈμ.
- λΉλκΈ° μμ
μ²λ¦¬
- λΉλκΈ° μ½λ(μ: setTimeout, API νΈμΆ)μμ μνλ₯Ό μ
λ°μ΄νΈν λλ **await act(async () => {...})**λ₯Ό μ¬μ©ν΄μΌ ν΄μ.
await act(async () => { await fetchData(); // λΉλκΈ° μμ μλ£ λκΈ° });
- λΉλκΈ° μ½λ(μ: setTimeout, API νΈμΆ)μμ μνλ₯Ό μ
λ°μ΄νΈν λλ **await act(async () => {...})**λ₯Ό μ¬μ©ν΄μΌ ν΄μ.
- ν
μ€νΈ λꡬ
- **@testing-library/react**μ ν¨κ» μ¬μ©ν λ actλ λλΆλΆ μλμΌλ‘ μ μ©λ©λλ€.
- νμ§λ§ λͺ μμ μΌλ‘ μ¬μ©ν΄μΌ ν λλ μμΌλ κ²½κ³ κ° λ¨λ©΄ νμΈν΄ 보μΈμ.
π ν μ€ μμ½
actλ React ν
μ€νΈμμ μν μ
λ°μ΄νΈμ νλ©΄ λ λλ§μ΄ μλ£λ νμλ§ ν
μ€νΈκ° μ§νλλλ‘ λμμ£Όλ ν¨μμμ.
ν
μ€νΈκ° λ μ ννκ³ μμ μ μΌλ‘ μλνλλ‘ κΌ μ¬μ©ν΄ μ£ΌμΈμ!