컴포넌트가 재렌더링되면 거기 안에 있는 자식컴포넌트는 항상 함께 재렌더링됩니다.
평소에는 별 문제가 없겠지만 자식컴포넌트가 렌더링시간이 1초나 걸리는 무거운 컴포넌트면 어쩔 것입니까.
부모컴포넌트에 있는 버튼 누를 때 마다 1초 버벅이는 불상사가 발생합니다.
그럴 땐 자식을 memo로 감싸놓으면 됩니다.
function Child(){
console.log('재렌더링됨')
return <div>자식임</div>
}
function Cart(){
let [count, setCount] = useState(0)
return (
<Child />
<button onClick={()=>{ setCount(count+1) }}> + </button>
)
}
콘솔로 확인해보시면 버튼을 누를때마다 Cart컴포넌트가 재렌더링될때마다 Child도 재렌더링됩니다.
평소엔 별 문제가 없겠지만 <Child>예가 렌더링이 2초정도 걸리는 컴포넌트면 누를 때마다 버벅거릴 수 있습니다.
이럴 때 memo라는 함수를 쓰면 "꼭 필요할 때만 <Child> 컴포넌트 재렌더링해주세요"라고 코드를 짤 수 있습니다.
memo()
momo()로 컴포넌트 불필요한 재렌더링을 막을 수 있습니다.
import {memo, useState} from 'react'
let Child = memo( function(){
console.log('재렌더링됨')
return <div>자식임</div>
})
function Cart(){
let [count, setCount] = useState(0)
return (
<Child />
<button onClick={()=>{ setCount(count+1) }}> + </button>
)
}
1. memo를 import 해와서
2. 원하는 컴포넌트 정의부분을 감싸면 됩니다.
근데 컴포넌트를 let 컴포넌트명 = function(){} 이런식으로 만들어야 감쌀 수 있습니다.
그럼 이제 Child로 전송되는 props가 변하거나 그런 경우에만 재렌더링됩니다.
Q. memo는 좋은거니까 막써도 되나요?
memo로 감싼 컴포넌트는 헛된 재렌더링을 안시키려고 기존 props와 바뀐 props를 비교하는 연산이 추가로 진행됩니다.
props가 크고 복잡하면 이거 자체로도 부담이 될 수 있습니다. 그래서 꼭 필요한 곳에만 사용합니다.
useMemo
useMemo는 useEffect와 비슷한 용도입니다.
컴포넌트 로드시 1회만 실행하고 싶은 코드가 있으면 거기 담으면 됩니다.
import {useMemo, useState} from 'react'
function 함수(){
return 반복문10억번돌린결과
}
function Cart(){
let result = useMemo(()=>{ return 함수() }, [])
return (
<Child />
<button onClick={()=>{ setCount(count+1) }}> + </button>
)
}
1. 예를 들어서 반복문을 10억번 돌려야하는 경우
2. 그 함수를 useMemo안에 넣어두면 컴포넌트 로드시 1회만 실행됩니다.
useEffect처럼 dependency도 넣을 수 있어 특정 state, prosp가 변할때만 실행할 수도 있습니다.
'프론트엔드 > react' 카테고리의 다른 글
react - state 변경함수 사용할 때 주의점 : async (0) | 2023.08.07 |
---|---|
React - 성능개선(useTransition, useDeferredValue) (0) | 2023.08.07 |
React - 성능개선(개발자도구 & lazy import) (0) | 2023.08.07 |
React - react-query (0) | 2023.08.07 |
React - localStorage (0) | 2023.08.05 |