반응형
이렇게 숫자가 혼자서 계속 올라가는 것을 만드려면 어떻게 해야 할까??
시도하다보면 useEffect를 쓰는 쪽으로 생각이 흘러간다.
처음에는 다음과 같이 작성하였다.
useEffect(() => {
setInterval(() => {
setCount(count);
}, 1000);
}, [count]);
return (
<>
<h1>{count}</h1>
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount((prevCount) => prevCount - 1)}>-</button>
<button onClick={() => setCount((prevCount) => prevCount + 1)}>+</button>
</>
);
그러니 이러한 버그가 나타났다.
그래서 clean-up함수를 추가해주었다.
(clean-up함수가 언마운트시가 아니라, 업데이트시 실행된다는 것을 알 수 있음, 참고)
import { useEffect, useState } from "react";
const initialCount = 0;
function FrequentlyChangableDependencyInEffect() {
const [count, setCount] = useState<number>(initialCount);
useEffect(() => {
const id = setInterval(() => {
setCount(count + 1);
}, 1000);
return () => clearInterval(id);
}, [count]);
return (
<>
<h1>{count}</h1>
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount((prevCount) => prevCount - 1)}>-</button>
<button onClick={() => setCount((prevCount) => prevCount + 1)}>+</button>
</>
);
}
export default FrequentlyChangableDependencyInEffect;
이렇게 하니 버그는 사라졌지만 매 업데이트마다 interval를 초기화하게 된다.
이는 clean-up되기 전에 실행될 기회를 한번밖에 얻지 못하는 것이다.
이는 비효율적일 수 있다.
공식문서에서는 다음과 같이
- 의존성 배열에 빈배열을 넣고,
- setState안에 callback을 넣으라고 하고 있다.(funtional update)
import { useEffect, useState } from "react";
const initialCount = 0;
function FrequentlyChangableDependencyInEffect() {
const [count, setCount] = useState<number>(initialCount);
useEffect(() => {
const id = setInterval(() => {
setCount((c) => c + 1); //functional update
}, 1000);
return () => clearInterval(id);
}, []);
return (
<>
<h1>{count}</h1>
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount((prevCount) => prevCount - 1)}>-</button>
<button onClick={() => setCount((prevCount) => prevCount + 1)}>+</button>
</>
);
}
export default FrequentlyChangableDependencyInEffect;
이렇게 작성하면 현재 state를 참조하지 않고 state를 변경할 수 있게 된다.
즉, 현재 state가 업데이트 될 때 마다 clean-up이 실행되는 로직을 피하여 count가 변하여도 clean-up이 실행되지 않는다.(count변화가 state 를 참조하지 않고 변경되기 때문)
- as-is : state업데이트-> clean-up실행 -> state 업데이트 -> clean-up 실행 ...
- to-be : state업데이트 -> state 업데이트 -> state 업데이트 ..... -> 언마운트시 clean-up실행(state변화가 state를 참조하지 않기 때문에 clean-up으로 이어지지 않음)
더 복잡한 경우(한 state가 다른 state를 의존하는 경우)는 useReducer를 사용하라고 하고 있다.
사실 회사에서 useReducer를 사용해봤었는데, 왜 사용했는지 모르고 그냥 기존에 useReducer를 사용한 코드였기 때문에
그대로 사용했었다.
이번기회에 useReducer를 왜 쓰는지 알아봐야 할 듯
참고
반응형
'개발 > React' 카테고리의 다른 글
useRef 로 관리하는 값이 바뀌었을 때 리렌더링 되지 않는 이유 (0) | 2022.10.03 |
---|---|
React.memo - Memoization을 이용한 불필요 리렌더링 없애기 (0) | 2022.09.18 |
useEffect의 cleanUp 함수에 대한 착각 : unmount시 발생하는 것이 아니다! (0) | 2022.08.12 |
Flux 패턴 (0) | 2022.08.11 |
Suspense (0) | 2022.08.10 |