본문 바로가기

React

React - Hooks (useCallback / React.Memo) (4)

 useCallback  
                               

 -  memoization 된 콜백 반환

 
의존성 배열의 값이 변하지 않으면 콜백 함수를 계속 재사용 할 수 있음

 

useCallback(() => {...}, [dependencies])

- 첫번째 인수: 저장할 함수

- 두번째 인수: dependency 배열

 

 

고차 컴포넌트
                               

- 컴포넌트를 가져와 새 컴포넌트를 반환하는 함수

컴포넌트 로직을 재사용하기 위한 React의 고급 기술로, React API의 일부가 아니며 React의 구성적 특성에서 나오는 패턴

 


React.Memo  
                               

- 컴포넌트의 props 가 바뀌지 않았다면, 리렌더링을 방지하여 컴포넌트의 리렌더링 성능 최적화 가능

 

 

위의 경우, 부모 컴포넌트가 리렌더링 되면서 prop이 바뀌지 않은 자식 컴포넌트도 리렌더링이 발생해 불필요한 연산이 실행 됨

 


 
React.memo는 고차 컴포넌트(Higher Order Component)로 컴포넌트가 동일한 props로 동일한 결과를 렌더링해낸다면 컴포넌트를 렌더링하지 않고 마지막으로 렌더링된 결과를 재사용함

React.memo는 props 변화에만 영향을 받음

import React, { useEffect, useState } from "react"

const TextView = ({ text }) => {
    useEffect(()=>{
        console.log(`Update :: Text : ${text}`)
    })

    return <div>{text}</div>
}
  
const CountView = ({ count }) => {
    useEffect(()=>{
        console.log(`Update :: Count : ${count}`)
    })

    return <div>{count}</div>
}
  
const OptimizeTest = () => {
    const [count, setCount] = useState(1)
    const [text, setText] = useState("")
  
    return (
        <div style={{ padding: 50 }}>
            <div>
                <h2>count</h2>
                <CountView count={count}/>
                <button onClick={() => setCount(count + 1)}>+</button>
            </div>
            <div>
                <h2>text</h2>
                <TextView text={text}/>
                <input onClick={(e) => setText(e.target.value)} />
            </div>
        </div>
    )
}
  
export default OptimizeTest;

 

React.memo로 최적화 전

 

Count의 값만 바뀌었음에도 TextView 컴포넌트도 렌더링 되는 현상 발생

 

import React, { useEffect, useState } from "react"

const TextView = React.memo(({ text }) => {
    useEffect(()=>{
        console.log(`Update :: Text : ${text}`)
    })

    return <div>{text}</div>
})
  
const CountView = React.memo(({ count }) => {
    useEffect(()=>{
        console.log(`Update :: Count : ${count}`)
    })

    return <div>{count}</div>
})
  
const OptimizeTest = () => {
    const [count, setCount] = useState(1)
    const [text, setText] = useState("")
  
    return (
        <div style={{ padding: 50 }}>
            <div>
                <h2>count</h2>
                <CountView count={count}/>
                <button onClick={() => setCount(count + 1)}>+</button>
            </div>
            <div>
                <h2>text</h2>
                <TextView text={text}/>
                <input onClick={(e) => setText(e.target.value)} />
            </div>
        </div>
    )
}
  
export default OptimizeTest;

 

React.memo로 최적화 후

 

React.memo로 감싸주면 다음과 같이 값이 바뀐 컴포넌트만 렌더링 됨을 확인할 수 있음

 

React.memo는 props가 갖는 복잡한 객체에 대하여 얕은 비교만을 수행하는 것이 기본 동작이기 때문에  다른 비교 동작을 원한다면, 두 번째 인자로 별도의 비교 함수를 작성해야 함

더보기
객체의 얕은 비교 추후 추가

 

'React' 카테고리의 다른 글

React - Hooks (useRef / useMemo) (3)  (0) 2023.02.23
React - Hooks (useState / useEffect) (1)  (0) 2023.02.05
React - SPA / MPA / CSR / SSR  (0) 2023.01.30