state가 변경되면서 컴포넌트가 리렌더링됨
부모 컴포넌트 리렌더링 -> 자식컴포넌트 리렌더링 -> 그 안에 무수한 컴포넌트 리렌더링
리렌더링을 안 해도 되는 상황인데 모두 리렌더링되서 느린것
함수형 컴포넌트에서는 컴포넌트를 만들고 나서 React.memo 함수로 감싸주면 최적화 가능
const MyComponent=({a, funcA, funcB})=>{
(...)
}
export default React.memo(MyComponent);
// MyComponent를 React.memo 함수로 감싸주면 a, funcA, funcB가 바뀌지 않는 이상 리렌더링 되지 않음
하지만... 여기서 끝이 아니다
funcA, funcB가 a를 참조한다면 a가 바뀔 때마다 funcA, funcB도 새롭게 만들어짐
해결 방법
const [todos, setTodos] = useState([]);
const onInsert = useCallback(text => {
const todo = {
text
}
// setTodos(todos.concat(todo)) ; // X
setTodos(todos => todos.concat(todo));
},[])
setTodos 함수를 사용할 때 새로운 상태를 파라미터로 넣는 대신
어떻게 업데이트 하는지 정의하는 함수를 넣으면 됨
그럼 useCallback 함수의 두 번째 파라미터에 특정 값을 넣지 않아도 됨
function reducer(todos, action){
switch(action.type){
case 'insert'
return todos.concat(todo);
}
}
const [todos,dispatch] = useReducer(reducer, []);
const onInsert = useCallback(text => {
const todo = {
text
};
dispatch({type:'insert' , todo});
},[])
useReducer를 사용하면 기존 코드를 많이 고쳐야 한다는 단점이 있지만
로직을 모아서 컴포넌트 바깥에 둘 수 있다는 장점이 있음.
결론
둘 다 성능이 비슷해서 골라서 사용하면 됨