- 컴포넌트가 리렌더링 되는 4가지 경우
- 자신이 전달받은 props가 변경될 때
- 자신의 state가 바뀔 때
- 부모 컴포넌트가 리렌더링될 때
- forceUpdate 함수가 실행될 떄
1. React.memo 최적화
- 마지막에 React.memo로 감싸주기
- 컴포넌트의 props가 바뀌지 않았다면 리렌더링x
import React from 'react'; import { MdCheckBoxOutlineBlank, MdCheckBox, MdRemoveCircleOutline, } from 'react-icons/md'; import cn from 'classnames'; import './TodoListItem.scss'; const TodoListItem = ({ todo, onRemove, onToggle }) => { const { id, text, checked } = todo; return ( <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> ); }; export default React.memo(TodoListItem);
2. useState에서 함수형 업데이트하기
- 기존
const onRemove = useCallback( (id) => { setTodos(todos.filter((todo) => todo.id !== id)); }, [todos], ); const onToggle = useCallback( (id) => { setTodos( todos.map((todo) => todo.id === id ? { ...todo, checked: !todo.checked } : todo, ), ); }, [todos], );
- 개선
const onRemove = useCallback((id) => { setTodos((todos) => todos.filter((todo) => todo.id !== id)); }, []); const onToggle = useCallback((id) => { setTodos((todos) => todos.map((todo) => todo.id === !id ? { ...todo, checked: !todo.checked } : todo, ), ); }, []);