React의 렌더링 조건
- props 변경될때마다
- state가 변경될때마다
💩 부모 컴포넌트가 다시 렌더링되면 해당 모든 자식의 컴포넌트도 불필요하게 다시 렌더링될 수 있음!
이를 위해 사용하는 것들👇👇👇
memoization
- 처음 계산해 놓은 결과를 메모리상에 저장해 두고, 그 저장된 메모리 주소를 필요할때 꺼내서 사용하는 방법
- 반환값을 캐싱하는 것
- 최적화 기법
memo(React.memo)
- 자식 컴포넌트를 메모이제이션함
- 리액트 고차 컴포넌트(HOC)임
* 고차 컴포넌트(HOC) : 어떤 컴포넌트를 인자로 받아서 최적화된 새로운 컴포넌트로 반환 - 🚫꼭 필요할때만 사용하기
1. 컴포넌트가 같은 props로 자주 렌더링 될때
2. 컴포넌트가 렌더링이 될때마다 복잡한 로직을 처리해야 할때 - 오직 Props 변화에만 의존하는 최적화 방법
but, 부모 컴포넌트가 렌더링될때마다 객체나 함수 props가 새로운 참조 값으로 생성되기때문에
자식 컴포넌트가 React.memo로 감싸져 있더라도 재렌더링이 발생할 수 있음!💩
그래서 이때 참조하는게 함수면 useCallback, 값이면 useMemo를 사용하여 재렌더링 방지!🌟
useCallback
- 함수를 메모이제이션하여 부모 컴포넌트가 다시 렌더링되더라도 같은 참조를 유지하게 하는 hook
- 인자로 들어오는 함수 자체를 메모이제이션함
- 콜백함수, 의존성 배열을 받음
- 렌더링 => component 함수 호출 => memoize 된 함수를 재사용
useMemo
- 값을 메모이제이션하여 부모 컴포넌트가 다시 렌더링되더라도 같은 참조를 유지하게 하는 hook
- 콜백함수 , 의존성배열을 받음
- return하는 값을 메모이제이션함
- useMemo를 남발하면 별도의 메모리 확보를 너무나 많이 하게 되기 때문에 오히려 성능이 악화💩
∴ 성능 최적화를 위해서만 사용
import { useMemo } from 'react';
import { filterTodos } from './utils.js'; //무거운 작업
export default function TodoList({ todos, theme, tab }) {
const visibleTodos = useMemo(
() => filterTodos(todos, tab),
[todos, tab]
);
return (
<div className={theme}>
<p><b>Note: <code>filterTodos</code> is artificially slowed down!</b></p>
<ul>
{visibleTodos.map(todo => (
<li key={todo.id}>
{todo.completed ?
<s>{todo.text}</s> :
todo.text
}
</li>
))}
</ul>
</div>
);
}
*useCallback은 함수를, useMemo는 값을!
- 렌더링시 함수 내부 변수는 초기화됨
- 초기화가 된다는건 새로운 객체가 다시 만들어지고, 메모리 주소도 새로 생성이 됨
=> 렌더링 전 변수와 렌더링 후 변수는 다름 - useEffect에서 의존성 배열은 결국 무한 렌더링이 발생
- 이를 해결하기 위해 useCallback, useMemo를 사용하여 함수 자체를 memoization해줌!
'리액트' 카테고리의 다른 글
[React]context api (0) | 2024.11.11 |
---|---|
[React]form태그 비제어 (0) | 2024.11.06 |
[React]useContext (0) | 2024.11.04 |
[React]useRef (0) | 2024.11.04 |
[React]useEffect (1) | 2024.11.04 |