- 컴포넌트 리렌더링 방지, 성능 최적화를 할 수 있다.
- 사용방법은 컴포넌트를 내보낼때 React.memo로 감싸주면 된다.
export default React.memo(CreateUser);
export default React.memo(UserList);
const User = React.memo(function User({user, onRemove, onToggle}){
const {username, email, id, active} = user;
useEffect(() => {
return ()=> {
}
}, [user]);
return (
<div>
<b
style={{
color: active ? 'green' :'black',
cursor: 'pointer',
}}
onClick={()=>onToggle(id)}
>
{username}
</b>
<span>({email})</span>
<button onClick={()=> onRemove(id)}>삭제</button>
</div>
);
})
- onRemove, onToggle을 살펴보면 deps에 users를 포함하고있다.
- users가 바뀌면 onRemove, onToggle도 바뀌고
<UserList>
입장에서 보면 onRemove, onToggle이 바뀌었으니 내부에 있는 것도 전부 리렌더링 해야한다.
- 그리고
<User>
역시 onRemove, onToggle이 바뀌었으니 리렌더링 해야한다.
- 이 문제를 해결하기 위해서 users를 참조해서는 안된다.
- useState의 함수형 업데이트를 이용하는 것이다.
- deps에 있는 users를 지워주고 setState에 함수형으로 업데이트 해준다.
const onCreate = useCallback(() => {
const user = {
id: nextId.current,
username,
email,
};
setUsers(users => [...users, user]);
setInputs({
username: '',
email: '',
})
nextId.current += 1;
},[username, email]);
const onRemove = useCallback(id => {
setUsers(users => users.filter(user => user.id !== id));
}, [])
const onToggle = useCallback(id => {
setUsers(users => users.map(user => user.id === id ? {...user, active: !user.active} : user))
},[])