React.memo와 useMemo, useCallback

김철회·2022년 10월 13일
0

memoization

useMemouseCallback의 차이를 알기 위해선 먼저 memoization이란 프로그래밍 기법을 먼저 알아두는 것이 좋다.

memoization
이전의 연산 결과를 저장해두고 동일하게 또 연산이 필요하면 저장해둔 결과를 활용하는 프로그래밍 기법.

memoization의 의미에서 볼 수 있듯이, useMemo와 useCallback은 이처럼 중복되는 연산을 줄이기 위해 사용한다.

React의 리렌더링

React는 3가지 조건에서 리렌더링 된다.
1) state가 변경 될 때
2) props가 변경 될 때
3) 부모 컴포넌트가 리렌더링 될 때

React는 리렌더링 될 때마다 컴포넌트를 다시 그린다. 그리고 컴포넌트 안에 있는 jsx, 함수 등을 매번 새로 그려낸다. 프로젝트나 사이트의 규모가 어마무시하게 크다고 가정 했을 때, 리렌더링 될 때마다 매번 새롭게 그린다면 그것은 곧 성능의 저하로 이어질 것이다.
이를 위해 존재하는 것이 React.memo와 useMemo, useCallback이다.

React.memo

React.memo는 '컴포넌트'를 메모이제이션한다.

1)

const Component = React.memo((props) => {
	return (
		컴포넌트~
	)})

2)

	const Componet = () => {
    return (
    	컴포넌트~
    )}
    
    export default React.memo(Component);

React.memo는 부모 컴포넌트로부터 넘겨 받아온 Props가 달라진 것이 없다면 미리 렌더링 해두었던 결과를 가져온다. 즉, 메모이제이션한 결과값이 있어 리렌더링 하지 않기 때문에 성능을 높일 수 있다.
단, React.memo는 props가 변경 됐는지만을 확인한다.

컴포넌트가 리렌더링 되면 컴포넌트 내부의 함수를 포함한 모든 객체들이 다시 그려진다. 자바스크립트는 기본적으로 값이 같더라도 참조하는 주소가 다르면 다른 객체로 보는데, 부모 컴포넌트에서 리렌더링 될 때 함수가 다시 그려지면서 같은 함수더라도 재생성된 함수 객체의 참조 주소가 달라 props가 변경 되었다고 판단한다. 이때 React.memo는 의도한대로 작동하지 않는다. 이러한 단점을 해소하기 위해 useCallback과 useMemo가 나왔다.

useCallback

useCallback은 '함수'를 return 한다.

	const testCallback = useCallback(()=>{
    	콜백에 사용할 함수(something);
    },[something])

useCallback은 deps안의 값이 바뀔 때마다 새로운 객체를 생성한다. React.memo는 부모 컴포넌트가 자식 컴포넌트에 props로 넘겨준 함수가 부모 컴포넌트에서 재생성 될 때(함수 객체가 재생성될 때), 참조하는 값이 달라진 것으로 인식하여 props가 바뀐 것으로 인식하고 자식 컴포넌트는 해당 함수를 재생성한다.
하지만 useCallback은 의존성 배열인 deps 안의 값이 바뀔 때에만 재생성하므로 성능을 더 끌어 올릴 수 있다.

useMemo

useMemo은 '값'를 return 한다.

	const testMemo = useMemo(()=>{
    	return useMemo에 사용할 함수(something);
    },[something])

위와 같이 사용하게 되면, 함수 연산에 의해 리턴된 값을 어느 한 부분에 저장해두었다가 리렌더링될 때 재생성하지 않고 함수의 리턴 값을 사용할 수 있다. 그리고 의존성 배열인 something이 바뀔 때는 업데이트가 된다.

성능을 높이는 메모이제이션 무조건 좋은 걸까?

React의 가장 큰 특징이자, 장점인 리렌더링에 의해서 여러번 함수가 재생성되고 이로 인해 Props를 받는 자식 컴포넌트도 리렌더링 되는 과정을 줄일 수 있다는 측면에서 보면 성능을 높일 수 있는 방법이 될 것이다. 하지만 이는 꼭 중요한 곳에서, 그리고 꼭 필요한 부분에서 사용하는 것이 좋다. 늘 과한 것보단 적당한 것이 좋은데, 그 이유는 결국 메모이제이션도 어느 한 메모리 공간을 차지하는 것이기 때문에 이러한 메모이제이션이 늘어나면 반대로 성능이 줄어들 것이다. 메모리 공간을 다른 것들도 사용해야 하는데 메모이제이션으로만 꽉 차있다고 생각해보면 이해가 쉬울 것이다.

profile
안녕하세요!

0개의 댓글