memo / useMemo / useCallback?
- 렌더링 이후의 값과 전의 값을 비교해서 같으면 재생성하지말라고 하는것
반드시 렌더링이 필요한곳에 사용하고 무분별한 사용은 금지
React.memo (컴포넌트)
- 메모이제이션 된
컴포넌트를 반환
(고차 컴포넌트)
- 부모 컴포넌트가 렌더링되면 자식 컴포넌트는 같이 렌더링 되는게 원칙이지만, memo를 사용하여 자식컴포넌트가 부모컴포넌트의 마지막으로 렌더링된 결과를 기억하여 부모컴포넌트의 prop이 같다면 리렌더링 되지않고
부모컴포넌트의 prop이 변할때만 렌더링이 되게 한다
- 즉, 부모컴포넌트에서 useState 훅을 사용했을때, 자식컴포넌트에 React.memo를 감싸주면 state값이 그대로면 리렌더링 되지않고 state값이 변하면 리렌더링 된다.
- https://ko.reactjs.org/docs/react-api.html#reactmemo
useMemo 변수(객체,배열)을 재사용
- 메모이제이션 된
연산 값(함수 실행의 결과)을 반환
의존성[]이 변경되었을 때
만 다시 실행되어 값을 return
- props를 받아 컴포넌트를 리렌더링하지 않고
마지막으로 렌더링된 결과를 재사용
특정한 값을 return
하여 memoriztion (함수도 값으로 인지 가능)
import React from "react";
function CommentIem({ title, content, likes }) {
const rate = React.useMemo(() => {
return likes > 10 ? "Good" : "Bad";
}, [likes]);
return (
<div>
<span>{likes}</span>
<br />
<span>{rate}</span>
</div>
);
}
export default CommentIem;
useCallback 함수를 재사용
- 메모이제이션 된
함수를 반환
리렌더링 시, 렌더링 전 최신 state 유지
- 컴포넌트가 리렌더링될 때마다 함수를 새로 만들지 않고
한번 함수를 만들고 재사용
- 함수안에서 사용하는 state, 함수등의 props가 있다면, 꼭
의존성[]
에 넣어줘야한다. 이 값을 넣어야 가장 최신값을 참조
의존성이 변경되었을 때만 새롭게 생성
되어 참조값이 변경
const onChange = useCallback((e) => {
setValue(e.target.value);
}, [])
const onSubmit = useCallback(
(e) => {
onInsert(value);
setValue('');
e.preventDefault();
},
[onInsert, value],
);
<form className="TodoInsert" onSubmit={onSubmit}>
<input
placeholder=" 할 일을 입력하세요"
value={value}
onChange={onChange}
<button type="submit">생성</button>
</form>
/>
memo와 useCallback을 함께 쓰자
- memo를 썼지만 state가 계속 변한다면 부모컴포넌트의 함수에 useCallback도 함께 써줘야한다.
부모컴포넌트의 다른 state가 변할때 useCallback으로 이전값을 기억해두지 않으면 함수가 다시 실행되면서 자식컴포넌트가 리렌더링되기 때문이다.
무조건 쓰는게 좋을까?
- 리액트에서 5번 렌더링 되는걸 4번, 3번으로 줄인다고 유의미한 성능향상을 가져오지는 않는다.
useMemo나 useCallback도 부가적인 연산이 필요하기 때문에 남용하게 된다면 오히려 예상치 못한 성능저하?를 가져올 수 있다.
따라서 성능 최적화를 위하여 사용되어야하지 렌더링을 방지하기 위해 사용하면 안된다