import React, { useState, useRef, useCallback } from 'react';
import TodoTemplate from './components/TodoTemplate';
import TodoInsert from './components/TodoInsert';
import TodoList from './components/TodoList';
//성능 최적화 편?
function createBulkTodos() {
const array = [];
for (let i = 1; i <= 2500; i++) {
array.push({
id: 1,
text: `할 일 ${i}`,
checked: false,
});
}
return array;
}
const AppCopy = () => {
const [todos, setTodos] = useState(createBulkTodos);
//고유 값으로 사용될 아이디.
// ref를 사용하여 변수 담기
const nextId = useRef(2501);
const onInsert = useCallback(
(text) => {
const todo = {
id: nextId.current,
text,
checked: false,
};
setTodos(todos.concat(todo));
nextId.current += 1; //nextId 1씩 더하기
},
[todos],
);
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],
);
return (
<TodoTemplate>
<TodoInsert onInsert={onInsert} />
<TodoList todos={todos} onRemove={onRemove} onToggle={onToggle} />
</TodoTemplate>
);
};
export default AppCopy;
chrome developer tools 로 성능 확인하기 => inspector => performace => record (녹화버튼) 클릭.. => 원하는 Action 완료후 멈춤.
Timing 이라는 곳에 들어가서 나의 파일을 확인하면 2.05초 가 걸렸다고 나옴....(사람들 컴퓨터마다 다르다고 한다...) ...근대 2초가 길은것인가? 솔직히 차이 느껴졌음...만약에 안좋은 컴퓨터 쓰는 사람이면...정말 답답할것 같음...
컴포넌트가 리렌더 되는 상황들
할일 1을 체크 할 경우 App 의 state 가 변경됨.
할일 1번만 update되면 되지만 2부터 2500까지 모두 update되면서 리렌덩이 느려지는것임.
shouldComponentUpdate 이 함수형에없으니 대신 React.memo() 사용
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);
props 가 바뀌지 않는 이상 리렌더링 하지 않도록 설정하는 함수형 컴포넌트.
그런데 onRemove 와 onToggle 을 사용하면 프로젝트의 배열이 바뀌기(update) 때문에 바꿔줘야함..
useState
예시 코드:
const[number,setNumber]=useState(0)
const onIncrease=useCallback(
()=>setNumber(prevNumber => prevNumber +1),[])
//prevNumber 는 현재 number 값을 가리킴
// 현재 숫자 값에서 +1을 업데이트 하라?
예: (업데이트를 어떻게 할것인지 정의해 주는 업데이트 함수)
실제 코드
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,
),
);
}, []);
결과