11장까지 오기위해 1 ~ 10장 을 두번 읽었습니다.
많은 데이터를 리턴하는 함수를 만들어서 2,500 개를 자동으로 생성했습니다.
const [todos.setTodos] = useState(createBulkTodos);
주의할 점은 useState의 기본값에 함수를 넣어 주었다는 것 입니다.(배열이 리턴됩니다.) 여기서 useState(createBulkTodos()) 라고 작성하면 리렌더링될 때마다 createBulkTodos 함수가 호출되지만, useState(createBulkTodos) 처럼 파라미터를 함수 형태로 넣어주면 컴포넌트가 처음 렌더링 될때만 createBulkTodo 함수가 실행됩니다!
컴포넌트는 다음과 같은 상황에서 리렌더링이 발생합니다.
컴포넌트의 props가 바뀌지 않았다면 리렌더링 하지 않도록 설정하여 함수형 컴포넌트의 리렌더링 성능을 최적화해 줄수 있습니다.
TodoListItem.js
const TodoListItem = ({ todo, onRemove, onToggle} => {
(...)
});
export default React.memo(TodoListItem);
이제 TodoListItem 컴포넌트는 todo, onRemove, onToggle 이 바뀌지 않으면 리렌더링을 하지 않습니다.
아래 처럼 바꿈, [] 이부분 주의
const onRemove = useCallback(id => {
setTodos(todo => todos.filter(todo => todo.id !== id));
}, [])
원래는 아래와 같았음 차이점 확실히 알고가면 좋을것 같습니다.
const onRemove = useCallback(
(id) => {
setTodos(todos.filter((todo) => todo.id !== id));
},
[todos],
);
어떤 객체A에서 참조로 복사한경우, 복사한 객체B를 수정했을 때,
B를 수정한경우 A도 수정되니깐 (같은거니깐)
A에서 B로 어떻게 수정됐는지 알수가 없어 비교가 안되니깐 그럼 최적화도 불가능해집니다.
그렇기 때문에 얕은복사를 해서 불변성을 유지해야하는데, 얕은복사도 그 안에 요소를 비교하면 사실 같은요소로 판단하니깐 깊은복사를 해줘서 불변성을 유지해야하는데.. 그럼 복잡해지니깐 immer 라는 라이브러리의 도움을 받으면 편하게 작업할수 있습니다.
리스트를 렌더링 할때 스크롤 아래에 있는 부분도 렌더링해서 비효율적입니다.
react-vitualized 를 사용하면 리스트 컴포넌트에서 스크롤되기 전에 보이지 않는 컴포넌트는 렌더링하지 않고 크기만 차지하게끔 할 수 있습니다. 그리고 만약 스크롤되면 해당 스크롤 위치에서 보여 주어야 할 컴포넌트를 자연스럽게 렌더링시키죠.