기능 구현에 급급한 코린이는 비효율성 같은건 따질 생각도 하지 못했다..!
useState를 쓸 경우 useState를 제외한 모든 값이 리렌더링 된다는 사실을 인지하지 못하고 있었다.
페이지가 리렌더링되는 과정을 살펴보고, 불필요한 리렌더링을 막을 수 있는 방법에 대해 알아보자!
let 버튼을 누를 경우 콘솔 값은 올라가지만, 리렌더는 일어나지 않는다. 또한, document.getElementbyID를 따로 쓰고 있지 않기 때문에 화면의 숫자도 따로 바뀌지 않는다.
반면에, state버튼을 누를 경우 콘솔 값과 함께 state값이 1씩 증가하는 것을 볼 수 있다. 그와 함께 전체 화면이 리렌더 되면서 let이 0으로 초기화되는 것을 볼 수 있다.
이를 통해 useState를 활용할 경우 state를 제외한 화면 전체가 리렌더링된다는 것을 확인할 수 있다.
[container.tsx]
export default function containerPage(){
console.log("컨테이너가 렌더링 됩니다.")
let countLet = 0
const [countState,setCountState] = useState(0)
const onClickCountLet = () => {
console.log(countLet+1)
countLet += 1
}
const onClickCountState = () => {
console.log(countState+1)
setCountState(countState+1)
}
return(
<div>
<div>================<div>
<h1>이것은 컨테이너 입니다.</h1>
<div> 카운트(let): {countLet} </div>
<button onClick={onClickCountLet}> 카운트(let) +1 올리기! </button>
<div> 카운트(state): {countLet} </div>
<button onClick={onClickCountState}> 카운트(state) +1 올리기! </button>
<div>================<div>
<MemoizationPresenterPage/>
</div>
)
}
[Presenter.tsx]
export default function MemoizationPresenterPage () {
console.log("프리젠터가 렌더링 됩니다.")
return(
<div>
<div>================<div>
<h1>이것은 프리젠터 입니다.</h1>
<div>================<div>
</div>
)
}
React에서 지원하는 memo를 통해 container가 리렌더 되더라도 presenter는 리렌더되지 않도록 막을 수 있다.
따라서 container에서 state 버튼을 클릭하더라도 presenter는 리렌더링 되지 않아 콘솔에 찍히지 않는다!
[presenter.tsx]
import {memo} from "react"
function MemoizationPresenterPage () {
console.log("프리젠터가 렌더링 됩니다.")
return(
<div>
<div>================<div>
<h1>이것은 프리젠터 입니다.</h1>
<div>================<div>
</div>
)
}
export defult memo(MemoizationPresenterPage)
useMemo( )를 사용할 경우 변수를 기억하기 때문에 return값이 고정된다.
따라서 useMomo는 그렇게 자주 사용하지 않는다..!
const aaa = useMemo(() => Math.random(), [])
console.log(aaa)
Math.random으로 생성된 랜덤한 값이 useMomo로 묶였기 때문에 처음 생성된 숫자가 계속해서 console에 찍힌다.
useCallback( )을 사용할 경우 해당 부분의 함수만 리렌더링을 막을 수 있다.
다만, state가 있는 함수를 useCallback으로 막을 시, state값이 고정되므로 state를 사용하기 위해선 prev를 활용해줘야 한다.
const onClickCountState = useCallback(() => {
// console.log(countState + 1); // state로 넣을 시 state값 고정!
setCountState((prev) => prev + 1);
}, []);