React.memo와 useCallback

트릴로니·2022년 1월 20일
0

React

목록 보기
13/15

React.memo()

  • 불필요한 re-rendering 피하기
  • functional compoenent를 최적화 해준다

작동원리

  • 인자로 받은 component의 prop의 값을 확인
  • prop의 값이 변화가 있을 때만 컴포넌트가 re-evaluated/re-executed되도록 해준다
  • 만약 parent component가 re-evaluate될 때 해당 컴포넌트의 prop의 값은 변화가 없을 경우 해당 컴포넌트는 re-executed되지 않음

React.memo()를 쓸 때 고려할 점

  • React.memo()는 리액트에게 부모 컴포넌트가 re-evaluation될 때마다 prop의 값을 확인하라고 시킴
  • 그러면 리액트는 두가지 일을 해야한다
  1. 이전의 prop의 값을 저장
  2. prop의 값을 비교
  • 즉 react.memo()를 쓴 다는 것은 조건없이 re-evaluate되는 작업의 비용과 컴포넌트의 prop의 value를 비교하여 re-evaluate되는 비용을 교환하는 것
  • 어느 비용이 더 높은지 판단하는 것은 고려할 점이 많다. 얼마나 많은 prop을 가지고 있는 지, 컴포넌트의 복잡도가 어느 정도인지 혹은 해당 컴포넌트의 자식 컴포넌트는 몇개가 달려있는지를 고려해야 하기 때문에 정확히 판단하는 것은 어려움

React.memo()를 쓰는 것이 유리할 때

  • Component tree가 매우 큰 경우 상위에 있는 컴포넌트에 React.memo()를 쓰면 불필요한 re-render cycles를 막을 수 있음

React.memo()를 쓰는 것이 불리할 때

  • Component tree가 작은 경우
  • 부모의 컴포넌트가 re-evaluate될 때마다 자식 컴포넌트의 prop의 값이 변하는 경우에는 어차피 컴포넌트가 re-render되어야 하므로 React.memo()를 쓸 필요가 없음

함수와 React.memo()

  • React.memo()는 prop을 비교할 때 얕은 비교하는데 원시 값의 경우 같은 값인지 객체나 배열, 함수같은 참조 값은 같은 주소 값을 갖는 지 확인한다
  • 그런데 함수의 경우 컴포넌트가 re-rendering될 때마다 새로 만들어진다. 즉 함수의 내용은 같으나 참조값이 달라지게 되어 React.memo()는 prop의 value가 달라졌다고 판단하고 컴포넌트를 re-excute하게된다.즉 이때 React.memo()를 쓰는 것은 memorizaion에 쓸데 없이 메모리가 낭비가 되는 것.

useCallback

  • 위의 문제점을 해결하기 위해 useCallback을 써준다.
  • useCallback은 특정 함수를 새로 만들지 않고 재사용하고 싶을 때 사용해 준다.
    -리액트에게 함수를 저장하고 싶다고 말해주는 것인데 즉 매변 re-excution될 때마다 함수를 재생산하지 않고 같은 메모리 위치에 function object를 저장시킨다.
  • 참조값이 같으므로 React.memo()가 prop의 값이 달라졌는지 비교 가능하다.

useCallback이 동작원리

let obj1={}
let obj2={}
obj1 === obj2
//false
obj2 = obj1
//obj1을 obj2의 메모리 위치를 가리키도록 만듦
obj1 === obj2
//true

useCallback(fn(), [])

첫번째 인자: 저장하고 싶은 함수
두번째 인자: deps

useCallback의 deps

  • 함수 클로저: 함수 내부의 지역 변수는 함수 스코프에 제한 받아 내부에서만 쓸 수 있음.
  • useCallback의 콜백함수에서 App의 지역변수인 allowToggle을 사용하는데 이때 이 allowToggle은 콜백함수안에 저장된다.
  • useCallback은 리액트에게 함수를 저장하라고 명령이 떨어지면 함수 내부에 allowToggle의 값도 함께 저장한다.
  • app function의 toggle state가 변해서 re-evaluate/ re-excute될 때 리액트는 useCallback으로 저장한 함수를 재생산 하지 않으므로 allowToggle의 값은 처음 컴포넌트가 실행되었을 때 값으로 저장되어 값이 업데이트 되지 못한다.
  • 그래서 deps에는 useCallback의 콜백함수의 어떤 변수가 값이 변할 때마다 함수를 재생산이 필요할 때의 변수를 넣어주면 최신 값을 사용할 수 있도록 만들어 준다.

0개의 댓글

관련 채용 정보