해결된 질문
22.03.30 11:23 작성
·
1.3K
2
답변 1
3
2022. 03. 30. 18:25
안녕하세요, 유상원님,
둘 다 좋은 질문을 해주셨습니다.
이 부분에 대해서는 저도 항상 고민하는 부분인데요, 제 생각 위주로 답변드리겠습니다.
1.
말씀하신대로 무분별한 memoization은 오히려 메모리를 낭비하게 됩니다.
useCallback과 useMemo를 사용하는 이유는 매번 렌더링마다 새로운 객체(함수 또는 값)를 생성하지 않기 위해서 사용하는 건데요,
예를 들어 반복적으로 리렌더링 되는 컴포넌트의 경우, 내부에서 선언하는 모든 함수나 변수들이 렌더링 시 마다 생성이 됩니다. 이 때, useCallback 또는 useMemo를 사용하여 렌더링 전, 후로 업데이트가 필요없는 함수나 변수에 대해서 불필요한 재할당을 방지할 수 있습니다.
하지만, 아래 코드와 같이 컴포넌트의 리렌더링이 곧 함수의 업데이트로 이어져야 한다면 useCallback을 사용할 필요가 없습니다.
function Component({ title }) {
const handleClick = useCallback(() => {
alert(title);
}, [title]);
return <button onClick={handleClick}>{title}</button>;
}
위 코드에 대해서 설명드리면, Component라는 컴포넌트가 리렌더링 되는 경우는 props로 내려오는 title이 변경되는 경우입니다. 그리고 그 안의 handleClick 함수는 title을 디펜던시로 가지고 있어서 title이 변경된 경우 함수를 업데이트합니다. 즉, Component가 리렌더링 되면 handleClick 함수는 항상 업데이트가 되는거죠.
다시 말해, handleClick 함수가 재활용되는 경우는 없습니다. 그렇기 때문에 useCallback 훅을 사용할 필요도 없는 거고요.
정리하면,
memoization 기능을 사용할 때는 memoization 후, 얼마나 재활용이 가능한 것인가를 잘 따져봐야 합니다.
위의 예시와 같이 한 번도 재활용이 안 되는 경우라면 오히려 memoization을 사용하면 안 되겠죠.
재활용이 된다고 해도 얼마나 많이 재활용이 될 것인가도 따져볼 수 있습니다. 100번의 리렌더링에서 1번만 재활용되는 값을 굳이 memoization을 할 필요는 없습니다. 이 기준은 해당 값의 특성과 중요도를 잘 따져보고 결정하시면 될 것 같습니다.
2.
Controlled Component와 Uncontrolled Component에 대해서 검색해보시길 추천드립니다.
말씀하신 대로 ref를 이용해서 특정 시점(완료버튼을 눌렸을 때와 같은)에서만 state를 업데이트 하실 수 있습니다.
하지만, 만약 값의 입력에 따라 화면의 일부 요소가 변해야 한다고 하면 얘기가 달라집니다.
예를 들어 타이핑 시, 글자 수를 보여준다거나 하는 식으로요.
만약 그런 식으로 매번 state를 업데이트해야한다고 하면 최대한 컴포넌트를 작은 단위로 분리하여 리렌더링에 대한 비용을 줄이고,
매번 리렌더링 되는 컴포넌트 안의 값들을 memoization 해두는 것도 좋습니다.
그럼 답변이 도웁되셨길 바라며, 강의에 관심을 가져주셔서 감사합니다. :)
2022. 03. 30. 21:39
자세한 답변 정말 감사합니다. 답변에 대해 고려해보면서 앞으로 코드를 짜보도록 하겠습니다. 감사합니다.