useMemo

크롱·2024년 1월 3일
0

React

목록 보기
11/18

useMemo

처음에 계산된 결과값(calculate함수 실행해서 나온 결과값)을 메모리에 저장.
즉 , 컴포넌트가 반복적으로 렌더링되어도, calculate함수를 다시호출하지않고, 이전에 이미 계산된 결과값을 메모리에서 꺼내와서 재사용

useMemo는 계산 비용이 큰 함수의 반환 값을 메모이제이션하여 리렌더링 시 재계산을 방지하는 데 사용

콜백함수- 우리가 메모이제이션 해줄 값을 return 하는 함수
이 콜백함수가 리턴하는 값= useMemo가 리턴하는 값=value

의존성 배열안의 값이 업데이트될때만 콜백함수를 다시 호출
->메모이제이션된 값 업데이트->다시 메모이제이션


사진 출처:별코딩 유튜브

예시

import React, { useState } from 'react'
import styled from 'styled-components'

const hardCalcul = number => {
  console.log('어려운 계산')
  for (let i = 0; i < 999999999; i++) {}
  return number + 10000
}

const easyCalcul = number => {
  console.log('짱쉬운 계산')
  return number + 1
}

export default function Home() {
  const [hardNum, setHardNum] = useState(1)
  const [easyNum, setEasyNum] = useState(1)

  const hardSum = hardCalcul(hardNum)
  const easySum = easyCalcul(easyNum)
  return (
    <Container>
      <Section>
        <h1>어려운 계산기</h1>
        <Input
          type="number"
          value={hardNum}
          onChange={e => setHardNum(parseInt(e.target.value))}
        />
        <span> + 10000 = {hardSum}</span>
      </Section>

      <Section>
        <h1>쉬운 계산기</h1>
        <Input
          type="number"
          value={easyNum}
          onChange={e => setEasyNum(parseInt(e.target.value))}
        />
        <span> + 1 = {easySum}</span>
      </Section>
    </Container>
  )
}

처음 렌더링되었을때,

어려운계산은 시간이 많이걸리니까, 쉬운 계산만 해야지! 하고 쉬운계산기의 input을 1 증가 시켰는데... 마치 어려운계산을 한것처럼 버벅거림

또한 콘솔창에는 어려운 계산도 출력되었다.

왜그럴까?
쉬운계산기에 숫자를 증가시켜주면
easyNumber state가 바뀐다. state가 바뀐다는 것은, 즉 App컴포넌트가 다시 렌더링이된다.

  const hardSum = hardCalcul(hardNum)
  const easySum = easyCalcul(easyNum)

그래서 App안에 잇는 hardsum과 easysum 모두 초기화가된다. 즉,hardCalcul도 실행됨.

easyNumber의 state를 변경할때, hardCalculate 함수가 불리지 않게 하고싶다... ==> useMemo를 쓰자

useMemo : 어떤 조건이 만족됐을때만, 해당 변수가 초기화되게한다.

만약 그 조건이 만족되지않았다면, app컴포넌트가 다시 렌더링되더라도, 다시 초기화시켜주는게 아니라 이전에 이미 갖고있던 값을 그대로 사용
= 메모이제이션

의존성배열안의 값이 바뀔때만 콜백함수가 실행댐.

  • useMemo 전
const hardSum = hardCalcul(hardNum)

👇

  • useMemo 후
  const hardSum = useMemo(() => {
    return hardCalcul(hardNum)
  }, [hardNum])



쉬운계산만 할때, 이제 hardCalcul은 실행되지않는^^




실용적인 예제2

import React, { useState, useEffect, useMemo } from 'react'
import styled from 'styled-components'

export default function UseMemoEx() {
  const [number, setNumber] = useState(0)
  const [isKorea, setIsKorea] = useState(true)

    const location = {
      country: isKorea ? '한국' : '외국',
    } 
  //만약 const location=isKorea? '한국':'외국'이면, 원시형데이터string니까 
  //number가 바껴도 useEffect안에 코드실행안댐.
  //오브젝트는 참조형데이터이기때문에, 항상 새로운 오브젝트가 할당되는거임.
 //=>useEffect안에 코드실행


  useEffect(() => {
    
    console.log('유즈이펙트 호출')
    ...엄청복잡한함수
  }, [location])
  
  
  return (
    <Container>
      <Section>
        <H1>하루에몇끼먹어요?</H1>
        <Input
          type="number"
          value={number}
          onChange={e => setNumber(e.target.value)}
        />
      </Section>
      <hr />
      <Section>
        <H1>어느 나라에 있어요?</H1>
        <p>나라 : {location.country}</p>
        <Btn onClick={() => setIsKorea(!isKorea)}>비행기 타자</Btn>
      </Section>
    </Container>
  )
}


하루에몇끼먹어요 밑 INPUT을 조절하면 number state가 바뀐다.
state가 변하니 역시 UseMemoEx이라는 함수가 다시 호출(렌더링)된다.
그러면, location이라는 오브젝트 변수도, 오브젝트가 또 할당이되는데,
오브젝트는 참조형데이터이기때문에, 항상 새로운 오브젝트가 할당되는거임.
그래서 내가 number의 input을 조절해도

useEffect(() => {
    
    console.log('유즈이펙트 호출')
    ...엄청복잡한함수
  }, [location])

이 코드가 실행되어, 불필요한 코드가 실행되는거다.

나는 isKorea의 state가 변할때만 location이 초기화됐으면좋겠다?
=> useMemo

  • useMemo 전
 const location = {
      country: isKorea ? '한국' : '외국',
    } 
  • useMemo 후
 const location = useMemo(() => {
    return { country: isKorea ? '한국' : '외국' }
  }, [isKorea])

참고 : 별코딩 유튜브

profile
👩‍💻안녕하세요🌞

0개의 댓글