inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

웹 게임을 만들며 배우는 React

6-5. useMemo와 useCallback

useState() 첫 번째 인자 관련

244

front

작성한 질문수 5

0

안녕하세요 선생님, 항상 좋은 강의 감사드립니다.

 

로또 추첨기를 복습하면서 함수형 컴포넌트 형태로  만들어보던 중에 아래와 같이 코드를 작성하게 됐습니다.

const Lotto = () => {

const [winNumbers, setWinNumbers] = useState(getWinNumbers);
...

 

useState()의 첫 번째 인자로 getWinNumbers()가 아닌 함수 자체를 넣어줬는데 정상 동작하는 것을 확인했습니다. 또한, useMemo()를 적용한 것처럼 화면이 리렌더링 되더라도 getWinNumber 함수가 재호출되지 않았습니다.

 

리액트 공식문서를 찾아봤지만 함수를 넣어주는 형태는 찾지 못했는데, 혹시 이게 유효한 문법일까요?

 

react

답변 1

0

제로초(조현영)

저러면 winNumbers가 getWinNumbers 함수 자체가 되어버립니다. 근데 아마도 setWinNumbers가 바로 호출되어 덮어씌워졌을 겁니다.

저렇게 하면 const [winNumbers, setWinNumbers] = useState(); 한 것이나 다름 없습니다.

0

front

답변 감사드립니다.

추가적으로 질문이 있습니다.

setWinNumbers가 바로 호출되어서 덮어씌워졌을 것이다 라고 말씀해주셔서 console.log()를 이용해 아래와 같이 로그를 찍어봤습니다.

console.log('%cfirst','background: red');
const [winNumbers, setWinNumbers] = useState(getWinNumbers);
console.log(winNumbers);
console.log('%csecond', 'background: blue');
...

setWinNumbers가 호출된 적이 없지만 winNumber가 정상적인 값을 가지고 있습니다.

 

추가적으로,

const [winNumbers, setWinNumbers] = useState();

와 같이 작성했을 경우에는 에러가 발생했습니다.

 

제가 무언가 놓치고 있다면 알려주시면 감사하겠습니다.

전체적인 소스 코드는 아래와 같습니다.

import React, { useCallback, useEffect, useRef, useState } from 'react';
import * as _ from 'lodash';
import Ball from './Ball';

const getWinNumbers = () => {
console.log('getWinNumbers() 함수가 호출되었습니다.');
const sevenNumbers = _.chain(_.range(1, 46))
.shuffle()
.take(7)
.value();

const bonusNumber = sevenNumbers[sevenNumbers.length - 1];
const sortedLottoNumbers = sevenNumbers.slice(0, 6).sort((a, b) => a - b);

return [...sortedLottoNumbers, bonusNumber];
}

const Lotto = () => {

console.log('%cfirst','background: red');
const [winNumbers, setWinNumbers] = useState(getWinNumbers);
console.log(winNumbers);
console.log('%csecond', 'background: blue');
const [winBalls, setWinBalls] = useState([]);
const [bonus, setBonus] = useState(null);
const [redo, setRedo] = useState(false);
const timeouts = useRef([]);

useEffect(() => {
console.log('%ctimeouts useEffect 시작', 'background: green');
_.chain(_.range(6))
.map(i => setTimeout(() => {
setWinBalls(prevWinBalls => [...prevWinBalls, winNumbers[i]]);
}, 1000 * (i + 1)))
.each(timeout => timeouts.current.push(timeout))
.value();

timeouts.current.push(setTimeout(() => {
setRedo(true);
setBonus(winNumbers[winNumbers.length - 1]);
}, 7000));

return () => {
console.log('%ctimeouts useEffect 리턴', 'background: green');
timeouts.current.forEach(clearTimeout);
}
}, [timeouts.current])

const onClickRedo = useCallback(() => {
console.log('redo 이벤트 발생!');
setWinNumbers(getWinNumbers());
setWinBalls([]);
setBonus(null);
setRedo(false);
timeouts.current = [];
}, [winNumbers]);

return (
<>
<div>
<div>당첨 숫자</div>
{winBalls.map(num => <Ball number={num} key={num}></Ball>)}
</div>

<div>보너스</div>
{bonus && <Ball number={bonus}></Ball>}
{redo && <button onClick={onClickRedo}>한 번 더!</button>}
</>
);
};

export default Lotto;

 

0

제로초(조현영)

아, 제가 착각했습니다. 아래 기능이라서 useState에 함수를 넣으면 그 함수가 실행됩니다. 보통은 비동기 작업을 한 후에 state를 만들 때 실행됩니다.

https://reactjs.org/docs/hooks-reference.html#lazy-initial-state

추가로 getWinNumbers를 useMemo로 감쌀 필요도 없어집니다. 처음 한 번만 실행돼서요.

0

front

많은 도움이 됐습니다. 답변 감사드립니다~

npm run dev 실행 시 포트가 안뜨는 문제

0

235

2

timeouts.current를 useEffect 의 input값으로 넣었을때

0

93

2

렌더링 테스트 코드 (Hooks)

0

92

1

Cannot find package 'react-refesh' 이런 에러 뜨시는 분들 보세요.

0

164

1

해당 에러 뜨는 분들 보세요. "Uncaught TypeError: ReactDom.createRoot is not a function"

1

204

1

강사님 레포지토리에서 코드 복사 시 master 브랜치 말고 react18 브랜치꺼 복붙하세요ㅠㅠ

0

105

1

useMemo와 useCallback 사용 시기

0

217

2

onRightClickTd가 작동을 하지 않습니다.

0

233

1

action.type 불러오는 방식

0

225

2

onClickRedo 질문

0

176

1

const Try = require(./Try) 빨간줄

0

258

1

npx webpack 실행시

0

323

1

지뢰찾기 강좌에서 빈칸들 한번에 열기 파트에서 여쭤보고싶은부분이 있어서 글 올립니다.

0

240

1

강좌에서 다루지 않은 기능들은 어떻게 학습하면 좋을까요?

0

318

1

react devtool이 enable 않됩니다.

0

544

2

React 랜더링이 되지 않습니다.

0

421

2

비동기로 동작하는 setState에 대해서

0

337

1

npm run dev 할 때 에러발생

0

494

2

memo, PureComponenet, shouldComponentUpdate 관련 질문

0

210

1

devMiddleware의 필요성

0

357

1

리액트에서 화살표 함수를 사용해야하는 이유

0

946

2

path.join관련질문

0

287

2

2-9. 웹팩 데브 서버와 핫 리로딩 설치과정 시 에러

0

384

1

next.js 에서 이와 비슷한 예제를 돌리고있는데 react랑 달라서 질문 드립니

1

502

4