function Counter() {
const [count, setCount] = useState(0);
console.log('+ ~ file: App.js ~ line 16 ~ Counter ~ count', count);
useEffect(() => {
const id = setInterval(() => {
setCount(count + 1);
console.log('+ ~ file: App.js ~ line 20 ~ id ~ count', count);
}, 1000);
return () => {
clearInterval(id);
console.log('cleanup 실행');
console.log(count);
};
}, []);
return <h1>{count}</h1>;
}
컴포넌트 관련 문제야. 아직 클린업에 대해서 정확하게 모르겠고 지금 감으로 하고 있는데
useEffect 의 두번째 파라매터에 배열을 주고 그 배열에 스테이트 값을 넣으면 그 스테이트가 변동이 있을 때만 작동한다.
빈배열이면 '최초' 랜더링에만 작동한다.
useEffect의 리턴은 클린함수이다.
그래서 저거 실행하면, 일단 빈배열이니 최초만 작동할거라 생각했어.
1. count 0 초기값
2. 컴포넌트 랜더링 (<- 0 넣음)
3. useEffect 실행 (1초 간격으로 count라는 state 1씩 증가하도록 설정)
4. 이제부터 useEffect 실행 안함.
이런식으로 말야. 근데 ㅋㅋㅋ 실제는 아래 같이 나옴.
카운터가 화면에 보여지기로는 1에서 멈춰있고 useEffect가 자꾸 실행되는데 useEffect에 넣은 함수에서 찍은 count값은 0임...
도당체 무슨 상황임;;?
ESLint가 빈배열 쓰지 말라고 하긴 하던데 이런 버그가 있다곤 생각도 못함. 라이프 사이클이 도대체 어떻게 돼먹은거야???
setInterval 콜백에 count 넣지 말고 setCount((prev) => prev + 1); 이런식으로 쓰셈
저 effect callback은 count가 처음 0인 상태에서 실행이 클로저로 묶일테니까 저 인터벌 안의 count는 계속 0일거고 ㅇㅇ
답변 ㄳㄳ. 내가 몰랐던 개념이라 계속 찾아서 해결하긴 했옹.