```
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;
}
}