코테이토 동아리/[코테이토]React 스터디 5기
11장. 컴포넌트 성능 최적화
Xerath(제라스)
2023. 2. 3. 12:39
728x90
반응형
- useState 사용 시
useState(func()) //이러면 리렌더링될 때마다 func함수가 호출됨.
useState(func) //이런 식으로 파라미터를 함수 형태로 넣어주면 컴포넌트가 처음 렌더링딜 때만 func 함수 실행함.
- 느려지는 원인 분석
1. 자신이 전달받은 props가 변경될 때
2. 자신의 state가 바뀔 때
3. 부모 컴포넌트가 리렌더링될 때
4. forceUpdate 함수가 실행될 때
컴포넌트의 개수가 많은데 모두 리렌더링을 하게 되면 느려지는 이슈 발생
-> 컴포넌트 리렌더링 성능을 최적화해줘야 함.
1. React.memo를 활용
import React from 'react';
import {
MdCheckBoxOutlineBlank,
MdCheckBox,
MdRemoveCircleOutline,
} from 'react-icons/md';
import './TodoListItem.scss';
import cn from 'classnames';
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); //이 부분처럼 처리해주면 됨.
-> 이런 식으로 React.memo를 써주면 컴포넌트의 props(todo, onRemove, onToggle, style)가 변경되지 않을 시 리렌더링하지 않음.
2. 함수가 바뀌지 않게 하기
1) useState의 함수형 업데이트
//이런 식으로 이전의 state(nowTodos)를 가지고 다음 state(nowTodos.concat(todo))를 선언해주면 됨.
setTodo(nowTodos => nowTodos.concat(todo));
2) useReducer 사용하기
useReducer를 사용하면 상태를 업데이트하는 로직을 모아서 컴포넌트 바깥에 둘 수 있음.
...
function createBulkTodos() {
const array = [];
for (let i = 1; i <= 2500; i++) {
array.push({
id: i,
text: `Todo ${i}`,
checked: false,
});
}
return array;
}
function todoReducer(todos, action) {
switch (action.type) {
case 'INSERT':
return action.tempTodos;
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;
}
}
const App = () => {
const [todos, dispatch] = useReducer(todoReducer, undefined, createBulkTodos); //이때 두번째 파라미터는 initialState값임.
const nextId = useRef(2501);
const onInsert = useCallback(
(text) => {
const tempTodos = [...todos, { id: nextId, text, checked: false }];
dispatch({ type: 'INSERT', tempTodos });
nextId.current += 1;
},
[todos],
);
...
3. 불변성 유지하는 방법
- 불변성을 지킨다: 기존의 값을 직접 수정하지 않으면서 새로운 값을 만들어 내는 것.
//이런 방식으로 하면 얕은 복사만...!!
const nextTodos = [...todos];
//이렇게 하면 새로운 객체를 할당하게 됨.
nextTodos[0] = {
...nextTodos[0],
checked: false,
};
4. react-virtualized를 활용
이게 뭔데?? 스크롤하기 전에 보이지 않는 컴포넌트들은 렌더링하지 않고 크기만 차지하게끔 하는 라이브러리.
모든 작업에 최적화를 할 필요는 없음!
하지만 보여줄 항목이 많아져서 업데이트가 종종 발생한다면 최적화 필요!
728x90
반응형