불필요할때에도 호출하여서 자원이 낭비되고 있다
이러한 상황에는 useMemo 라는 Hook 함수를 사용하면 성능을 최적화 할 수 있다
const countActiveUsers = users => {
console.log('확인...');
return users.filter(user => user.active).length;
}
const count = useMemo(() => countActive(users), [users]);
//input에서 값이 입력하는 와중에도 함수가 호출됨
// const count = countActive(users);
useMemo 는 특정 결과값을 재사용 할 때 사용하는 반면,
useCallback 은 특정 함수를 새로 만들지 않고 재사용하고 싶을때 사용한다.
useCallback 을 사용한다고 해서 바로 최적화가 되는것이 아니고, 컴포넌트 렌더링 최적화 작업을 해주어야만 성능이 최적화된다.
const onToggle = useMemo(
() => () => {
/* ... */
},
[users]
);
const onModify = useCallback(
() => {
setInputs({
username: users.username,
email: users.email,
id: users.id,
});
},
[inputs]
);
최적화 -> 함수형으로 바꾸고 degs에서 없애기
//전
const onRemove = useCallback(
id => {
setUsers(users.filter(user => user.id !== id));
},
[users]
);
//후
const onRemove = useCallback(
id => {
setUsers(users => users.filter(user => user.id !== id));
},
[]
);
컴포넌트의 props 가 바뀌지 않았다면, 리렌더링을 방지하여 컴포넌트의 리렌더링 성능 최적화를 해줄 수 있다
이 함수를 사용한다면, 컴포넌트에서 리렌더링이 필요한 상황에서만 리렌더링을 하도록 설정해줄수있다.
그냥 감싸주면 된다.
export default React.memo(UserList);
button 에 onClick 으로 설정해준 함수들은, 해당 함수들을 useCallback 으로 재사용한다고 해서 리렌더링을 막을 수 있는것은 아니므로, 굳이 그렇게 할 필요 없다.
추가적으로, 렌더링 최적화 하지 않을 컴포넌트에 React.memo 를 사용하는것은, 불필요한 props 비교만 하는 것이기 때문에 실제로 렌더링을 방지할수있는 상황이 있는 경우에만 사용.
추가적으로, React.memo 에서 두번째 파라미터에 propsAreEqual 이라는 함수를 사용하여 특정 값들만 비교를 하는 것도 가능.
export default React.memo(
UserList,
(prevProps, nextProps) => prevProps.users === nextProps.users
);
하지만, 이걸 잘못사용한다면 오히려 의도치 않은 버그들이 발생하기 쉽다.
예를 들어, 함수형 업데이트로 전환을 안했는데 이렇게 users 만 비교를 하게 된다면,
onToggle 과 onRemove 에서 최신 users 배열을 참조하지 않으므로 심각한 오류가 발생 할 수 있다