State Vs. Prev
Front-end ReactState vs. Prev
State란 리액트 컴포넌트에서 데이터를 담기 위한 상자라고 보면 좋다. 이 상자에 담긴 내용은 함수가 모두 끝나게 되면 화면에 렌더되게 된다. State 글에서 사용했던 Count incrementer 예제를 잠시 가져와보자.
// Model Counter example
const [ count, setCount ] = useState(0)
function increment(){
setCount(count + 1)
}
return (
<div>
<div>{count}</div>
<button onClick={increment}>Increment</button>
</div>
)
위 코드를 화면에 출력하면 버튼을 클릭할 때마다 카운터가 하나씩 증가하며 숫자 증가가 정상적으로 반영된다.
하지만, count를
n개씩 증가하기 위해 setCount
를 여러번 호출하게 되면 의도하던 상황이 쉽게 발생하지 않는 것을 확인할 수 있다.
const [count, setCount] = useState(0); // count = 0
function handleClickIncrement() {
setCount(count + 1); // 실제 count를 가져온다. count는 0이므로 0 + 1 = 1이 된다.
setCount(count + 1); // 1이 state에 담겼지만 여전히 count는 0이므로 0 + 1 = 1이 된다.
setCount(count + 1); // 1이 state에 담겼지만 여전히 count는 0이므로 0 + 1 = 1이 된다.
setCount(count + 1); // 최종적으로 1이 state에 담겨 화면에 1이 반영된다.
// count = 1이고, 리렌더가 된다.
}
return (
<div>
<div>{count}</div>
{/* Count 는 1이 된다 */}
<button onClick={handleClickIncrement}>Increment</button>
</div>
);
위와 같은 로직에 따라 count
를 4번 불렀음에도 count
는 1씩만 증가하게 된다.
의도한대로 count
가 4개씩 증가하게 만드려면 prev
라는 임시 저장공간을 사용하여 코드를 작성해야 한다.
const [count, setCount] = useState(0); // count = 0
function handleClickIncrementWithPrev() {
setCount((prev) => prev + 1); // 임시 저장공간에서 count가 있는지 본다. 없으면 실제 count를 가져온다.
setCount((prev) => prev + 1); // 임시 저장공간에 count = 1이 있다. 1 + 1 = 2 가 된다.
setCount((prev) => prev + 1); // 임시 저장공간에 count = 2이 있다. 2 + 1 = 3 이 된다.
setCount((prev) => prev + 1); // 임시 저장공간에 count = 3이 있다. 3 + 1 = 4 가 된다.
// count = 4이고, 리렌더가 된다.
}
return (
<div>
<div>{count}</div>
{/* Count 는 4가 된다 */}
<button onClick={handleClickIncrementWithPrev}>
Increment With Prev
</button>
</div>
);
이렇게 prev
를 사용하게 되면 임시 저장공간에 있는 값을 먼저 꺼내오고, 만약 임시 저장공간이 비어있다면 기본 state
를 불러오게 된다.