22.11.07 17:02 작성
·
241
0
작성한 코드는 아래와 같습니다.
제로초님과 코드가 다른 부분은
useRef 선언 부분 [] -> null,
useEffect deps , useEffect return부분입니다.
useRef를 배열이 아닌 상태로 사용하여 setTimeout을 설정시 문제되는 점이 있을까요?
useEffect 함수 return 부분에 clearTimeout사용법이 저렇게 사용하는게 맞나요?
onClick할 경우 새로운 번호를 winNumbers에 할당돼서 useEffect deps 를 winNumbers로 설정했습니다. 알맞게 잘 적용된걸까요?
이 코드로하면 잘 실행되고 마운트와 언마운트시 콘솔도 잘 찍힙니다.
import React, { useEffect, useRef, useState } from "react";
import Ball from "./Ball";
function getWinNumbers() {
console.log("getWinNumbers");
const numbers = Array(45)
.fill()
.map((v, i) => i + 1);
const shuffle = [];
while (numbers.length > 0) {
shuffle.push(
numbers.splice(Math.floor(Math.random() * numbers.length), 1)[0]
);
}
const bonusNumber = shuffle[shuffle.length - 1];
const winNumbers = shuffle.slice(0, 6).sort((a, b) => a - b);
return [...winNumbers, bonusNumber];
}
function Lotto() {
const [winNumbers, setWinNumbers] = useState(getWinNumbers());
const [winBalls, setWinBalls] = useState([]);
const [bonus, setBonus] = useState();
const [redo, setRedo] = useState(false);
const timeout = useRef(null);
useEffect(() => {
console.info("useEffect start !");
for (let i = 0; i < winNumbers.length - 1; i++) {
timeout.current = setTimeout(() => {
setWinBalls((prevState) => [...prevState, winNumbers[i]]);
}, (i + 1) * 1000);
}
timeout.current = setTimeout(() => {
setBonus(winNumbers[6]);
setRedo(true);
}, 7000);
return () => {
console.info("useEffect end !");
timeout.current = clearTimeout();
};
}, [winNumbers]);
const onClickRedo = () => {
setWinNumbers(getWinNumbers());
setWinBalls([]);
setBonus(null);
setRedo(false);
};
return (
<>
<div>당첨 숫자</div>
<div>
{winBalls.map((i) => (
<Ball key={i} number={i} />
))}
</div>
<div>보너스</div>
{bonus && <Ball number={bonus} />}
{redo && <button onClick={onClickRedo}>한 번 더!</button>}
</>
);
}
export default Lotto;
답변 1
0
2022. 11. 08. 20:02
지금 clearTimeout이 전혀 작동하지 않습니다. clearTimeout(아이디) 처럼 해야 하는 겁니다. 그리고 setTimeout이 배열이 아니라서 마지막 것만 취소되고 앞에 것들은 취소되지 않습니다.
redo 때문에 에러가 숨겨진 겁니다.