성능 최적화를 위하여 연산된 값을 useMemo 라는 Hook 을 사용하여 재사용 하는 방법을 알아보자
App 컴포넌트에서 아래와 같이 countActiveUsers 라는 함수를 만들어서, active 값이 true 인 사용자의 수를 세어서 화면에 렌더링 해보자
App.js
import React, {useRef, useState} from 'react';
import CreateUser from './components/CreateUser';
import UserList from "./components/UserList";
function App() {
function countActiveUsers(users) {
console.log("active 값이 ture 인 유저의 수를 센는중...");
return users.filter(user => user.active).length;
}
const [inputs, setInputs] = useState({
username: '',
email: ''
});
const {username, email} = inputs;
const onChange = e => {
const { name, value } = e.target;
setInputs({
// spread
...inputs,
[name]: value
});
};
// useState 를 사용하여 컴포넌트의 상태로 관리
const [users, setUsers] = useState([
{
id: 1,
username: 'velopert',
email: 'public.velopert@gmail.com',
active: true
},
{
id: 2,
username: 'tester',
email: 'tester@example.com',
active: false
},
{
id: 3,
username: 'liz',
email: 'liz@example.com',
active: false
}
]);
const nextId = useRef(4);
const onCreate = () => {
// 나중에 구현 할 배열에 항목 추가하는 로직
// ...
const user = {
id: nextId.current,
username,
email
};
// concat 함수
setUsers(users.concat(user));
// spread 함수
// setUsers([
// //spread 문법
// ...users,user
// ]);
setInputs({
username: '',
email: ''
});
nextId.current += 1;
};
const onRemove = id => {
// user.id 가 파라미터로 일치하지 않는 우너소만 추출해서 새로운 배열을 만듬
// = user.id 가 id 인 것을 제거함
setUsers(users.filter(user => user.id !== id));
}
const onToggle = id => {
setUsers(
users.map(user =>
user.id === id ? {...user, active: !user.active} : user
)
);
};
const count = countActiveUsers(users);
return (
<>
<CreateUser
username={username}
email={email}
onChange={onChange}
onCreate={onCreate}
/>
<UserList users={users} onRemove={onRemove} onToggle={onToggle}/>
<div>활성 사용자 수 : {count}</div>
</>
);
}
export default App;
** 참고
const count 함수는 우리가 useState 로 지정해둔 객체들 보다 먼저 생성하면 안됌.
당연히 렌더링 할 객체가 없으니 에러뜸ㅇㅇ

countActiveUsers 함수에서 콘솔에 메시지를 출력하도록 한 이유는, 이 함수가 호출 될 때마다 알수 있게 하기 위함!
근데, 여기서 발생하는 한가지 문제
input 의 값을 바꿀때도 countActiveUsers 함수가 호출됨;

활성 사용자 수를 세는 건 users 에 변화가 있을때만 세야되는건데 input 값이 바뀔 때에도 컴포넌트가 리렌더링 되므로 자원이 낭비되는중
이럴때 useMemo Hook 함수를 사용하여 성능을 최적화 시켜보자
App.js
import React, {useMemo, useRef, useState} from 'react';
import CreateUser from './components/CreateUser';
import UserList from "./components/UserList";
function App() {
function countActiveUsers(users) {
console.log("active 값이 ture 인 유저의 수를 센는중...");
return users.filter(user => user.active).length;
}
const [inputs, setInputs] = useState({
username: '',
email: ''
});
const {username, email} = inputs;
const onChange = e => {
const { name, value } = e.target;
setInputs({
// spread
...inputs,
[name]: value
});
};
// useState 를 사용하여 컴포넌트의 상태로 관리
const [users, setUsers] = useState([
{
id: 1,
username: 'velopert',
email: 'public.velopert@gmail.com',
active: true
},
{
id: 2,
username: 'tester',
email: 'tester@example.com',
active: false
},
{
id: 3,
username: 'liz',
email: 'liz@example.com',
active: false
}
]);
const nextId = useRef(4);
const onCreate = () => {
// 나중에 구현 할 배열에 항목 추가하는 로직
// ...
const user = {
id: nextId.current,
username,
email
};
// concat 함수
setUsers(users.concat(user));
// spread 함수
// setUsers([
// //spread 문법
// ...users,user
// ]);
setInputs({
username: '',
email: ''
});
nextId.current += 1;
};
const onRemove = id => {
// user.id 가 파라미터로 일치하지 않는 우너소만 추출해서 새로운 배열을 만듬
// = user.id 가 id 인 것을 제거함
setUsers(users.filter(user => user.id !== id));
}
const onToggle = id => {
setUsers(
users.map(user =>
user.id === id ? {...user, active: !user.active} : user
)
);
};
const count = useMemo(() => countActiveUsers(users), [users]);
return (
<>
<CreateUser
username={username}
email={email}
onChange={onChange}
onCreate={onCreate}
/>
<UserList users={users} onRemove={onRemove} onToggle={onToggle}/>
<div>활성 사용자 수 : {count}</div>
</>
);
}
export default App;
useMemo 의 첫번째 파라미터에는 어떻게 연산할지 정의하는 함수를 넣어주면 되고
두번째 파라미터에는 deps 배열을 넣어주면 됨
deps 배열의 내용이 바뀌면 등록한 함수를 호출해서 값을 연산하고 바뀌지 않으면 이전에 연산한 값을 재사용함.

'JS Library > React' 카테고리의 다른 글
| React.memo (0) | 2022.05.25 |
|---|---|
| useCallback 를 사용하여 함수 재사용 (0) | 2022.05.25 |
| React Developer Tools (0) | 2022.05.24 |
| useEffect 를 사용하여 마운트, 언마운트, 업데이트 시 할 작업 선택 (0) | 2022.05.23 |
| 배열에 항목 수정하기 (0) | 2022.05.20 |
| 배열에 항목 제거하기 (0) | 2022.05.20 |