이전에 연산된 값을 재사용하는 방법을 알아보자
예를 들어서 전에 연습한 리액트 앱에서 녹색글씨로 활성화된 user의 수를 세는 함수를 만든다고 해보자.
function countActiveUsers(users) {
console.log('활성 사용자 수를 세는중 ...');
return users.filter(user => user.active).length;
}
배열의 항목 중에서 active 가 true인 항목의 갯수를 리턴하는 countActiveUsers
함수이다.
이 함수를 변수에 할당하고
const count = countActiveUsers(users);
App.js
의 return 에 Dom 을 추가하여 결과화면을 출력해보자.
return (
<div style={style}>
<CreateUser username={username} email={email} onChange={onChange} onCreate={onCreate}/>
<UserList users = {users} onRemove={onRemove} onToggle={onToggle}/>
<div>활성 사용자 수: {count}</div>
</div>
);
user의 액티브상태가 변경됨에 따라서 활성사용자의 수가 바뀐다.
그런데, 상태가 변경되는 것은 useState함수가 호출된것으로 리렌더링 되는 것이고, 컴퍼넌트가 리렌더링 되면 그 부모요소 또한 리렌더링 된다. 그말은 곧 input 창에 텍스트를 하나하나 적어 넣는 것또한 useState로 호출하므로 계속 리렌더링이 되는 것이다.
글씨 하나하나 적을 때마다 사용자수를 세는 중이라는 문구가 출력된다.... 지금이에 몇 안되는 유저의 수이지만, 만약 수천 수만개의 유저를 리렌더링한다면, 사이트의 속도가 느려질 것이다.
이런 문제를 해결할 때 사용할 수 있는 것이 useMemo 라는 훅이다.
useMemo는 특정 값이 바뀌었을 때만 특정 함수를 실행하고, 값이 바뀌지 않은 경우에는 리렌더링 할때 이전의 값을 재사용할수 있게 해준다.
변수에 countActiveUsers
를 할당ㅎ나 count 변수에 useMemo()
를 씌워준다.
const count =useMemo(() => countActiveUsers(users), [users]);
이렇게 하면 최적화가 끝난 것이다.
users
배열의 값이 변경될 때만 활성화 유저의 수를 세기 때문에 글씨를 입력해도
countActiveUsers
가 호출되지 실행되지 않는 것이다.