[React] setInterval, setState를 같이 쓸 때 오류 해결
ㅇ...이게 머노...?
3초마다 배경색을 바꿔주려고 했는데 처음엔 잘 되다가 몇 분 지나면 광란의 파티가 된다......
왜 그런지 Console 창에 color를 띄워보니 막무가내로 바뀌었다가 유지되다가 난리였다...
const [color, setColor ]= useState("#F9CC82");
const colorChange = useRef<any>(null);
useEffect(() => {
setInterval(() => {
console.log(color);
if(color === "orange") setColor("pink")
else if(color === "pink") setColor("purple")
else if(color === "purple") setColor("orange");
colorChange.current.style = `background-color: ${color};`;
}, 3000);
}, [])
위 코드가 그 문제의 코드이다.
const [color, setColor ]= useState("#F9CC82");
const colorChange = useRef<any>(null);
useEffect(() => {
setInterval(changeColor, 2000)
}, [color])
function changeColor() {
console.log(color);
if(color === "#F9CC82") {
console.log("change 1");
setColor("#E2B4BA");
} else if(color === "#E2B4BA") setColor("#F9CC82");
colorChange.current.style = `background-color: ${color};`;
}
사실 setInterval 함수에 대해 잘 모르는 상태로 사용해본 거라서
setInterval을 구글링하면서 찾아보니 함수형태로 사용하는 경우도 있길래 사용해봤다.
그리고 color state가 바뀔 때마다 렌더링하게끔 했는데........ 이렇게 하니 맨 위 영상처럼 난리 부르스가 났다.
그래서 어떻게 고쳤는가?
const [color, setColor ]= useState("#F9CC82");
const side = useRef<any>(null);
useEffect(() => {
const interval = setInterval(() => {
if(color === "#F9CC82") {
setColor(color => "#E2B4BA");
} else if(color === "#E2B4BA") setColor(color => "#C6B5D7");
else if(color === "#C6B5D7") setColor(color => "#A7D0D7");
else if(color === "#A7D0D7") setColor(color => "#F9CC82");
side.current.style = `background-color: ${color};`;
}, 3000);
return () => clearInterval(interval);
}, [color])
위 코드가 최종본이다.
일단 setInterval에서 조건에 따라 색을 바꾸고, setInterval의 반환값을 interval 변수에 할당한다.
여기서 끝내면 setState가 무진장 실행된다.
따라서 clearInterval을 해주어 색바꾸는 동작을 한 번만 하게끔 만들어주면 해결!
뭐가 문제였지?
const [number, setNumber] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
console.log(number);
setNumber((number) => number + 1);
}, 1000);
}, [number]);
위 코드를 실행해보자.
그러면 위 사진과 같이 무한으로 Console에 출력이 되고, 일정하게 증가하는 것이 아니라 무작위로 출력된다.
이유는 아직 잘 모르겠다... setState가 비동기적으로 실행돼서 그런 거 아닐까...?
아무튼 저 에러를 해결하려면 clearInterval을 사용한다.
const [number, setNumber] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
console.log(number);
setNumber((number) => number + 1);
}, 1000);
return () => clearInterval(interval);
}, [number]);
clearInterval 함수는 실행중인 Interval 함수를 멈추는 것인데, 이게 있어야 setNumber 함수가 3초에 한 번 실행된다.
이거 오류 이유가 너무 궁금했는데 아무리 구글링해도 안 나와서 옾챗에 물어봤는데 다 모르신다...
아시는 분은 댓글 남겨주세요...