일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- BlockFormattingContext
- 부모요소의 패딩 무시
- transition
- debouncing
- alias설정
- 화살표2개
- 함수형프로그래밍
- 서초구보건소 #무료CPR교육
- DOM
- vite
- parent padding
- ?? #null병합연산자
- 제어컴포넌트
- useQueryClient
- 조건부스타일
- 문제해결
- createPortal
- 부모패딩
- accordian
- tailwindCSS
- BFC
- CustomHook
- Carousel
- ㅡ
- 리액트
- ignore padding
- react
- twoarrow
- QueryClient
- es6
Archives
- Today
- Total
프론트엔드 첫걸음
Todo App 성능개선 (React.memo + 함수형 setState) 본문
리액트를 다루는 기술 10장, 11장
1. 임의로 많은 데이터 입력하기
function createBulkTodos() {
const array = [];
for (let i = 0; i < 2500; i++) {
array.push({
id: i,
text: `${i} 번째 할일`,
checked: false,
});
}
return array;
}
const App = () => {
const [todos, setTodos] = useState(createBulkTodos);
const nextId = useRef(2501);
useState 안에 넣는 초기값에 함수 createBulkTodos() 라고 넣지 않고, createBulkTodos 함수를 넣으면 컴포넌트가 처음 렌더링 될 때만 createBulkTodos 함수가 실행된다.
2. 성능측정하기
1. 크롬 확장프로그램 React Developer Tools 설치
2. Profiler 녹화버튼을 누르고 화면에 변화가 반영되면 녹화 한번 더 눌러 결과 확인
3. 컴포넌트
3. 느려지는 원인
리렌더링이 발생하는 상황은 다음과 같다.
- 자신이 전달받은 props가 변경될 때
- 자신의 state가 바뀔 때
- 부모컴포넌트가 리렌더링 될 때
- forceUpdate함수가 실행될 때
현재 1개만 클릭해도 나머지 2499개가 모두 리렌더링 되는상황. TodoListItem컴포넌트가 받은 props (todo) 가 바뀌지 않았을 때도 리렌더링 되는 것이 문제이다.
4. React.memo를 사용하여 컴포넌트 성능 최적화
- react.memo는 컴포넌트에 들어가는 모든 props를 확인한 뒤, 이를 기존의 props 값과 비교하도록 리액트에 전달한다.
그리고 props의 값이 바뀐 경우에만 컴포넌트를 재실행 및 재평가 한다.
부모컴포넌트가 변경되었음에도 자식컴포넌트에 내려주는 props는 변하지 않았다면 컴포넌트의 실행을 건너뛴다.
재실행되지 않는 자식컴포넌트에 포함된 다른 컴포넌트들도 재실행되지 않는다.
const TodoListItem = ({ todo, onRemove, onToggle }) => {
const { id, text, checked } = todo;
return (
<div className="TodoListItem">
<div
className={checked ? 'checkbox checked' : 'checkbox'}
onClick={() => onToggle(id)}
>
{checked ? <MdOutlineCheckBox /> : <MdCheckBoxOutlineBlank />}
<div className="text">{text} </div>
</div>
<div className="remove" onClick={() => onRemove(id)}>
<IoIosRemoveCircleOutline />
</div>
</div>
);
};
export default React.memo(TodoListItem);
5. useState의 함수형 업데이트
setState함수의 인자로 상태 대신 이전 상태를 전달하여 상태를 업데이트하는 함수 를 넣어준다.
- 리팩토링 전
setState(todos 배열)
todos 배열 상태를 기준으로 update= todos가 바뀔때마다 useCallback 함수 재생성 해서 setState 안의 상태 업데이트해야함const onRemoveHandler = useCallback( (id) => { setTodos(todos.filter((todo) => todo.id !== id)); }, [todos], );
=> 의존성 배열에 todos 넣음
- 리팩토링 후
setState(todos 이전상태를 전달하여 상태를 업데이트 하는 함수)
바로 이전상태를 전달하여 상태를 업데이트 한다 = todos 바껴도 이전 상태를 기준으로 업데이트 하는 함수는 바뀌지 않음const onRemoveHandler = useCallback( (id) => { setTodos(todos => todos.filter((todo) => todo.id !== id)); }, [], );
=> 의존성 배열에 todos 넣을 필요 없음
6. 리팩토링 후 성능 확인
'개발 공부 > React' 카테고리의 다른 글
immer 사용법 (0) | 2022.08.29 |
---|---|
불변성을 지키면서 setState (0) | 2022.08.28 |
Redux (0) | 2022.08.23 |
Styled Component 심화 1 - Component Selector (0) | 2022.08.18 |
Form 제출 시 input값 가져오는 두가지 방법 (0) | 2022.08.14 |