자, 저번 강의의 출력값을 보시면
소수인지 아닌지 계산하는 함수의 ouput 또한
이 버튼을 클릭할 때마다 출력되고 있습니다
이 코드는
counter가 바뀔 때마다 실행되는데
이것이 타당한 이유는
이 isPrime 함수가
counter 컴포넌트 함수 안에서
직접적으로 불러져서
실행되는 것이기 때문입니다
즉 이 컴포넌트 함수가 바뀔 때마다입니다
그리고 이 함수가
이 log 부분이 기재되어 있는 곳입니다
이제 이 함수는 그저 데모 목적으로 있는 것입니다
그럼에도
이 함수는 결국
이 initalAccount 값을 입력값으로 씁니다
그리고 이 값은 오로지
여기에 새로운 값을 입력하고 '설정'을 클릭할 때만 바뀝니다
지금은 아직 작동하지 않지만
추후에 고쳐보겠습니다
하지막 지금 이 부분에서만
새로운 initialCount 값을 받아내고
isPrime이 새로운 결과를 냅니다
그것 말고는 initialCount는 바뀌지 않으며
오직 counter 컴포넌트 함수만이
재실행되는데 그 이유는 counter 상태가 바뀌고
isPrime은 언제나 같은 결과를 만들어내기 때문입니다
하지만 그건 더 복잡한 기능을 수행하는 함수와
더 많은 성능을 요하는 계산이 있을 땐
문제가 될 수 있습니다
지금 같은 경우는 아니지만
이것도 매우 단순한 계산은 아닙니다
특히 여기에 더 큰 숫자를 입력하면
예를 들어 100만이나, 1조 같은 숫자들
매번 이 코드들을 재실행하는 것은
아무리 전과 같은 결과를 낸다고 해도
효율적이지 않습니다
그러므로 memo를 사용해
컴포넌트 함수 실행을 방지하고 싶다면
컴포넌트 함수 내에 불러와진
일반 함수들의 실행도
방지해야 합니다
즉 입력값이 바뀌지 않는 이상 그렇습니다
리액트가 제공하는 훅이
이런 상황과 문제를 위해서입니다
바로 useMemo 훅입니다
memo와 혼동해서는 안 되고
memo는 컴포넌트 함수를 감싸는데 사용했습니다
이전 강의들에서 설명드렸던 내용입니다
useMemo는 컴포넌트 함수 안에 있는
일반 함수들을 감싸고
그들의 실행을 방지합니다
useMemo는 사실
복잡한 계산이 있을 때만 사용해야 합니다
예를 들어, 여기서 우리가
isPrime이 실행되는 걸 방지하고 싶다면
그리고 useMemo를 사용해서
함수를 전달하고
예를 들어, 이 익명의 화살표 함수를 전달하면
그러면 우리가 실행을 방지하고자 하는 함수의
결과를 반환해줍니다
그러니까 이 익명의 함수는
이제 isPrime으로 불리는 것이죠
useMemo는 의존성 배열도 필요로 합니다
useCallback이 그랬던 것과 같습니다
useMemo의 개념이 이제
리액트로 하여금 이 함수를 실행시키고
useMemo로 전달합니다
이 익명의 화살표 함수입니다
그런 다음 이 실행의 결과인
isPrime을 불러온 결과를 최종적으로 저장합니다
이 익명 함수에 반환되었기 때문입니다
그리고 이 함수들은 의존성들이 하나라도
바뀔 경우에만 재실행됩니다
그러니까 빈 의존성 배열이 있다면
이건 절대 재실행되지 않습니다
바뀔 수 있는 의존성이 없기 때문입니다
하지만 여길 보시면
이미 경고 메시지가 보입니다
initialCount를 의존성으로 추가해야 하기 때문입니다
그래야 isPrime이 입력으로 사용하기 때문입니다
그리고 initialCount가 바뀌면
isPrime은 다른 결과를 내게 됩니다
그러므로 initialCount를 값으로 추가해야 합니다
이 의존성 배열 안에 추가하면 됩니다
그리고 useMemo를 사용해서
마지막에 isPrime만이 재실행되어야 합니다
initalCount가 바뀌는 경우에 해당합니다
하지만 이 counter 상태가 바뀌면
실행되지 않을 것이며
이걸 저장하고 돌아가서 새로고침하고
이것도 지워주면
제가 '증가하기'를 클릭하니
더 이상 isPrime 함수 내의
output이 출력되지 않습니다
한편,
제가 새로운 counter 값을 설정하면 여기 output이 출력됩니다
하지만 제가 강조하고 싶은 건
useMemo를 남용해서는 안 된다는 것입니다
여러분의 함수들을 전부 감싸는데 사용해서는 안 됩니다
memo와 마찬가지로 추가적인
의존성 값 비교를 수행해야 하기 때문입니다
그리고 예를 들어
매 컴포넌트 함수가 실행될 때마다
재실행되어야 하는 함수가 있다면
이 추가적인 확인 과정은 그다지 적절하지 않고
그저 성능을 낭비할 뿐입니다
한편으로는
지나친 실행을 피할 수 있으며
그리고 어떤 코드를 실행할지에 따라
소요 시간이 길 수 있는 경우
useMemo를 사용하는 것이 더 합리적입니다
그러니 memo와 마찬가지로 항상 신경써서 사용해야 합니다
하지만 적재적소에 활용한 경우
여러분의 리액트 앱 성능을 개선하는 데 도움을 줄 수 있습니다