Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 리액트
- 어노테이션
- spring
- 깃허브
- merge
- 트랜잭션
- springboot
- list
- Spring legacy Project
- 객체
- mysql
- java
- 영속성 컨텍스트
- 상속
- @Bean
- github
- Spring 개발환경 설정
- 자동주입
- 스프링 컨테이너
- 자바
- 의존성주입
- 이클립스
- 스프링
- DI
- react
- @transactional
- pom.xml
- JVM
- 빈
- 인터페이스
Archives
- Today
- Total
DEVLOG
[React] 성능 최적화 기법 1. useCallback 본문
useCallback이란?
함수형 컴포넌트에서 사용할 수 있는 React Hook 중 하나이다.
사용 이유
컴포넌트가 리렌더링 되는 조건은 다음과 같다.
1. 자신의 state가 변경되었을 때
2. 자신의 props가 변경되었을 때
3. 부모 컴포넌트가 렌더링될 때
... 등등
만약 A 컴포넌트의 변화가 B 컴포넌트에는 어떠한 영향도 끼치지 않는데, 위와 같은 이유로 리렌더링이 불필요하게 자주 발생한다면 성능을 저하시키는 원인이 될 것이다.
이처럼 무분별한 리렌더링을 막고 싶다면 useCallback을 사용하면 된다.
특정 함수에 useCallback을 사용하면 최초 렌더링 시 한 번만 생성되므로, 리렌더링 될 때마다 새로 만들지 않고, 재사용할 수 있다는 장점이 있다.
이러한 useCallback을 사용하기 위해서 먼저 React.memo로 리렌더링을 방지하고자 하는 대상 컴포넌트를 래핑해야 한다.
* React.memo란?
메모이제이션의 기법 중 하나로, 해당 컴포넌트의 props가 변경되지 않는다면 다음 렌더링 시 메모이징된 내용을 그대로 사용할 수 있도록 한다.
예제를 보자.
App.js
import DiaryEditor from './DiaryEditor';
import { useState, useRef, useEffect, useMemo, useCallback } from 'react';
const App = () => {
const [data, setData] = useState([]);
// API 호출로 더미데이터 set
const getData = () => {
...
setData(...);
};
useEffect(() => {
getData();
}, [])
// useCallback
const onCreate = useCallback((author, content, emotion) => {
const newItem = {
...
};
setData((data) => [newItem, ...data]);
}, []);
return (
<div className="App">
<DiaryEditor onCreate={onCreate} />
...
</div>
);
}
export default App;
DiaryEditor.js : data 추가 컴포넌트
import React, { useEffect, useState, useRef } from 'react';
// useCallback 사용 전 : App으로부터 props로 받은 onCreate 때문에 DiaryEditor는 변경사항 없는데도 App 리렌더링 되면 자동 리렌더링 됨
// useCallback 사용 후 : props 변경되지 않는 한, 재사용되므로 리렌더링 되지 않음
const DiaryEditor = ({ onCreate }) => {
useEffect(() => {
console.log("DiaryEditor 렌더"); // 단 한 번 호출됨
})
...
const handleSubmit = () => {
onCreate(state.author, state.content, state.emotion);
...
}
return <div className='DiaryEditor'>
...
</div>
};
// React.memo(컴포넌트) 래핑
export default React.memo(DiaryEditor);
만약 예제에서 useCallback을 사용하지 않았다면, data의 수정, 삭제 컴포넌트의 기능이 동작할 때마다 App 컴포넌트의 state인 data가 update되어 App 컴포넌트가 리렌더링 되고, (어떠한 변화도 없는) 그의 자식인 DiaryEditor 컴포넌트까지 리렌더링 되었을 것이다. 지금은 두 세개의 컴포넌트뿐이지만, 최소 수십개 이상의 프로젝트에서도 위처럼 동작한다면 매우 비효율적일 것이다. 그렇기에 useCallback 과 같은 훅을 사용해 성능 최적화가 되도록 해야 한다.
'JavaScript > React' 카테고리의 다른 글
[React] 이벤트 bind 함수 이해하기 (0) | 2022.09.01 |
---|---|
[React] State 사용 (0) | 2022.08.31 |
[React] 개발환경 구축 (0) | 2022.08.21 |
Comments