처리된 값을 재사용하는 useMemo를 이용하여 성능 최적화를 할 수 있다.
이전에 사용한 유저 리스트에서 active된 user의 수를 카운트해주는 함수를 추가해보자.
import React, { useState, useRef } from "react";
import UserList from "./UserList";
import CreateUser from "./CreateUser";
const countActiveUser = users => {
console.log("카운트");
return users.filter(user => user.active).length;
};
//active user의 수
export default function App() {
const [inputs, setInputs] = useState({
username: "",
age: ""
});
const { username, age } = inputs;
const [users, setUsers] = useState([
{
id: 1,
username: "Kim",
age: 20
},
{
id: 2,
username: "Lee",
age: "30"
},
{
id: 3,
username: "Choi",
age: "40"
}
]);
const nextId = useRef(4);
const onInputChange = e => {
const { value, name } = e.target;
setInputs({
...inputs,
[name]: value
});
};
const onCreate = () => {
const user = {
username,
age,
id: nextId.current,
active: false
};
setUsers([...users, user]);
setInputs({
username: "",
age: ""
});
nextId.current += 1;
};
const onRemove = id => {
setUsers(
users.filter(user => {
return user.id !== id;
})
);
};
const onToggle = id => {
setUsers(
users.map(user => {
return user.id === id ? { ...user, active: !user.active } : user;
})
);
};
const count = countActiveUser(users);
return (
<div>
<CreateUser
username={username}
age={age}
onChange={onInputChange}
onCreate={onCreate}
/>
<div>activeUser : {count}</div>
<UserList users={users} onRemove={onRemove} onToggle={onToggle} />
</div>
);
}
여기서 문제점이 발생한다. input 값을 변경하면 불필요하게 카운트가 실행이 된다는 것이다.
따라서 불필요한 호출을 방지하기 위해서 값을 저장해놓고 변경될 때에만 호출이 될 수 있게 useMemo를 사용해준다.
import React, { useState, useRef, useMemo } from "react";
import UserList from "./UserList";
import CreateUser from "./CreateUser";
const countActiveUser = users => {
console.log("카운트");
return users.filter(user => user.active).length;
};
export default function App() {
const [inputs, setInputs] = useState({
username: "",
age: ""
});
const { username, age } = inputs;
const [users, setUsers] = useState([
{
id: 1,
username: "Kim",
age: 20
},
{
id: 2,
username: "Lee",
age: "30"
},
{
id: 3,
username: "Choi",
age: "40"
}
]);
const nextId = useRef(4);
const onInputChange = e => {
const { value, name } = e.target;
setInputs({
...inputs,
[name]: value
});
};
const onCreate = () => {
const user = {
username,
age,
id: nextId.current,
active: false
};
setUsers([...users, user]);
setInputs({
username: "",
age: ""
});
nextId.current += 1;
};
const onRemove = id => {
setUsers(
users.filter(user => {
return user.id !== id;
})
);
};
const onToggle = id => {
setUsers(
users.map(user => {
return user.id === id ? { ...user, active: !user.active } : user;
})
);
};
const count = useMemo(() => countActiveUser(users), [users]);
return (
<div>
<CreateUser
username={username}
age={age}
onChange={onInputChange}
onCreate={onCreate}
/>
<div>activeUser : {count}</div>
<UserList users={users} onRemove={onRemove} onToggle={onToggle} />
</div>
);
}