```
function createBulkTodos() {
const array = [];
for (let i = 0; i <= 2500; i++) {
array.push({
id: i,
text: `할 일 ${i}`,
checked: false,
});
}
return array;
}
```
리렌더링 되는 상황
TodoApp의 경우
const TodoListItem = ({ todo, onRemove, onToggle }) => {
...
}
export default React.memo(TodoListItem);
setTodos를 사용할 때 새로운 상태로 파라미터를 넣는 대신 상태 업데이트를 어떻게 할지 정의해 주는 업데이트 함수 넣기
일반 setTodos
const onInsert = useCallback(
(text) => {
const nextTodo = {
id: nextId.current,
text,
checked: false,
};
setTodos([...todos, nextTodo]);
nextId.current += 1;
},
[todos],
);
함수형 업데이트 사용한 setTodos
setTodos((todos) => {
return [...todos, nextTodo];
});
nextId.current += 1;
}, []);
insert, remove, toggle에 모두 적용
useReducer로 type을 설정해 재호출 막을 수 있다.
reducer 함수
function todoReducer(todos, action) {
switch (action.type) {
case 'INSERT':
return [...todos, action.nextTodo];
case 'REMOVE':
return todos.filter((todo) => todo.id !== action.id);
case 'TOGGLE':
return todos.map((todo) =>
todo.id === action.id ? { ...todo, checked: !todo.checked } : todo,
);
default:
return todos;
}
}
dispatch 설정
const [todos, dispatch] = useReducer(todoReducer, undefined, createBulkTodos);
...
const onToggle = useCallback((id) => {
dispatch({ type: 'TOGGLE', id });
}, []);
const [todos, dispatch] = useReducer(todoReducer, undefined, createBulkTodos);
얕은 복사
const todo= [{ .. }, { .. }]
const deepTodo = [...todo]
deepTodo[0]={
...deepTodo[0],
{...}
}
리스트에 관련 컴포넌트는 리스트 내부의 컴포넌트 뿐만 아니라 리스트로 사용하는 컴포넌트 자체도 최적화를 해줘야 한다.
export default React.memo(TodoList)
리스트 관련 컴포넌트 : 리스트와 리스트 아이템 최적화 !!
import {List} from 'react-virtualized';
List 컴포넌트: 해당 리스트의 전체 크기(width, height, 전체 개수), 각 항목의 높이, 각 항목을 렌더링할 때 사용하는 함수, 배열을, 을 props로 넣어야한다.
return (
<List
className="TodoList"
width={495}
height={513}
rowCount={todos.length}
rowHeight={57}
rowRenderer={rowRenderer}
list={todos}
style={{ outline: 'none' }}
/>
);
rowRenderer 함수
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],
);
div로 감싸고 props로 전달받은 style 적용
const TodoListItem = ({ todo, onRemove, onToggle, style }) => {
const { id, text, checked } = todo;
return (
<div className="TodoListItem-virtualized" style={style}>
...
</div>
TodoListItem.scss 작업
.TodoListItem-virtualized {
& + & {
border-top: 1px solid #dee2e6;
}
&:nth-child(even) {
background: #f8f9fa;
}
}