-
카테고리
-
세부 분야
프론트엔드
-
해결 여부
해결됨
hooks 재실행에 대해
23.05.07 19:23 작성 23.05.07 20:58 수정 조회수 219
0
6-5 로또 강의에서 useMemo 가르치시기 전에 "hooks의 특성상 전체가 계속 다시 실행된다"라는 말씀을 하셨고, useState(초기값)도 불필요하게 계속 재실행되기에 함수 결과값으로 기억하기 위해 useMemo를 쓴다는 것인데
그 말씀대로라면 강의 초반 구구단 챕터에서
const [first, setFirst] = React.useState(Math.ceil(Math.random() * 9))
const [second, setSecond] = React.useState(Math.ceil(Math.random()*9))
const [value, setValue] = React.useState('')
const [result, setResult] = React.useState('')
const inputRef = React.useRef()
const submit = (e) => {
e.preventDefault()
if(Number(value)===first * second) {
setResult('정답')
setValue('')
setFirst(Math.ceil(Math.random()*9))
setSecond(Math.ceil(Math.random()*9))
} else {
setResult('땡')
setValue('')
}
inputRef.current.focus()
}
submit함수에 setFirst(Math.ceil(Math.random()*9)), setSecond(Math.ceil(Math.random()*9))를 안써도 되지 않나요?
가장 위에 useState(Math.ceil(Math.random() * 9)) 으로 초기값을 지정해놨으니까 어차피 렌더링 될 때마다 useState가 재실행 되니까 setFirst와 setSecond는 필요 없는 것 아닌가요?
답변을 작성해보세요.
0
조현영
지식공유자2023.05.07
해당 부분은 구구단 정답을 맞췄을 때 새로 first와 second 값을 정해서 다음 문제를 내는 부분입니다.
useState의 특징은 처음에 값이 없을 때는 초깃값을 받아들이고, 한 번 값이 넣어진 상태에서 다음에 실행될 때는 초깃값을 무시합니다
처음 setFirst(Math.ceil(Math.random()*9)), setSecond(Math.ceil(Math.random()*9))할 때는 값이 세팅되고,
리렌더링이 되어 두 번째로 setFirst(Math.ceil(Math.random()*9)), setSecond(Math.ceil(Math.random()*9))할 때는 Math.ceil은 실행이 되나, 이미 초깃값을 넣었으므로 useState가 그 값을 무시해버립니다.
Bell Vise
질문자2023.05.07
그럼 마찬가지로 로또도
function getWinNumbers() {
console.log('getWinNumbers');
const candidate = Array(45).fill().map((v, i) => i + 1);
const shuffle = [];
while (candidate.length > 0) {
shuffle.push(candidate.splice(Math.floor(Math.random() * candidate.length), 1)[0]);
}
const bonusNumber = shuffle[shuffle.length - 1];
const winNumbers = shuffle.slice(0, 6).sort((p, c) => p - c);
return [...winNumbers, bonusNumber];
}
const Lotto = () => {
const [winNumbers, setWinNumbers] = useState(getWinNumbers())
useState(getWinNumbers())로 처음에 한번 초기값으로 값이 넣어진 상태인데
훅스의 특성으로 전체가 다시 실행될 때 왜 계속 console.log에 getWinNumbers가 찍히나요?
console.log에 getWinNumbers가 찍힌다는 것은 getWinNumbers()가 재실행된다는 것이고, 그 말은 즉슨 useState(getWinNumbers())가 재실행된다는 얘기 아닌가요??
그래서 useMemo를 쓰는 것이고
조현영
지식공유자2023.05.07
getWinNumbers가 실행은 된다니까요? 방금 전 답변에도 Math.ceil이 실행은 된다고 말씀드렸습니다. 다만 처음 이후 리렌더링 때는 그 반환값을 무시할 뿐이죠. 이전 답변 다시 읽어보세요.
처음 setFirst(Math.ceil(Math.random()*9)), setSecond(Math.ceil(Math.random()*9))할 때는 값이 세팅되고,
리렌더링이 되어 두 번째로 setFirst(Math.ceil(Math.random()*9)), setSecond(Math.ceil(Math.random()*9))할 때는 Math.ceil은 실행이 되나, 이미 초깃값을 넣었으므로 useState가 그 값을 무시해버립니다.
참고로 요즘에는 useMemo 대신 아예 lazy initialization을 사용합니다. useState(getWinNumbers)를 하면 됩니다.
답변 1