React/일정관리 프로젝트
[React TodoList] 불변성, 최적화, 렌더링 최적화
Judith Hopps
2023. 3. 15. 09:44
반응형
리액트 투두리스트 보완
불변성의 중요성
불변성이란?
기존의 값을 수정하지 않으면서 새로운 값을 만들어 내는 것
TodoList 컴포넌트 최적화 하기
리스트 내부에서 사용하는 컴포넌트도 최적화 해야 하고,
리스트로 사용되는 컴포넌트 자체도 최적화해 주는 것이 좋다.
react-virtualized를 사용한 렌더링 최적화 하기
리스트 컴포넌트에서 스크롤 되기 전에 보이지 않는 컴포넌트는 렌더링 하지 않고 크기만 차지하게 끔 할 수 있다.
스크롤 이벤트 발생 시, 스크롤 위치에서 보여 주어야 할 컴포넌트를 자연스럽게 렌더링 시킨다.
이 라이브러리를 사용하면 낭비되는 자원을 아주 쉽게 아낄 수 있다.
사용방법
1. 패키지 설치
npm install react-virtualized
2. UI 컴포넌트 px 알아보기
3. TodoList.js 수정
import React, { useCallback } from 'react';
import { List } from 'react-virtualized';
import TodoListItem from './TodoListItem';
import './TodoList.scss';
const TodoList = ({ todos, onRemove, onToggle }) => {
const rowRenderer = useCallback(
({ index, key, style }) => {
const todo = todos[index];
return (
<TodoListItem
todo={todo}
key={key}
onRemove={onRemove}
onToggle={onToggle}
style={style}
/>
);
},
[onRemove, onToggle, todos],
);
return (
// 각 항목의 길이는 가로 512, 세로 56.67(첫번째 칸은 테두리가 없어 세로 56) 이다.
<List
className="TodoList"
width={512} // 전체 크기
height={453.44} // 전체 높이
rowCount={todos.length} // 항목 개수
rowHeight={56.67} // 항목 높이
rowRenderer={rowRenderer} // 항목을 렌더링할 때 쓰는 함수
list={todos} // 배열
style={{ outline: 'none' }} // List에 기본 적용되는 outline 스타일 제거
/>
);
};
export default React.memo(TodoList);
4. TodoListItem
import React from 'react';
import {
MdCheckBoxOutlineBlank,
MdCheckBox,
MdRemoveCircleOutline,
} from 'react-icons/md';
import cn from 'classnames';
import './TodoListItem.scss';
const TodoListItem = ({ todo, onRemove, onToggle, style }) => {
const { id, text, checked } = todo;
return (
<div className="TodoListItem-virtualized" style={style}>
<div className="TodoListItem">
<div
className={cn('checkbox', { checked })}
onClick={() => onToggle(id)}
>
{checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
<div className="text">{text}</div>
</div>
<div className="remove" onClick={() => onRemove(id)}>
<MdRemoveCircleOutline />
</div>
</div>
</div>
);
};
export default React.memo(TodoListItem);
5. TodoListItem.scss
.TodoListItem-virtualized {
&:nth-child(even) {
background-color: #f8f9fa;
}
& + & {
border-top: 1px solid #dee2e6;
}
}
.TodoListItem{
padding: 1rem;
display: flex;
align-items: center;
.checkbox{
cursor: pointer;
flex : 1;
display: flex;
align-items: center;
svg {
font-size: 1.5rem;
}
.text {
margin-left: 0.5rem;
flex : 1
}
&.checked {
svg{
color : #22b8cf;
}
.text{
color :#adb5bd;
text-decoration: line-through;
}
}
}
.remove {
display: flex;
align-items: center;
font-size: 1.5rem;
color:#ff6b6b;
cursor: pointer;
&.hover {
color :#ff8787;
}
}
}
Final , 성능 측정
반응형