React/Velopert's React
[React] Study #17 | useCallback
yevdev
2021. 10. 8. 11:07
๐กuseCallback
- useCallback์ useMemo์ ๋น์ทํ Hook
- useMemo๋ ํน์ ๊ฒฐ๊ณผ๊ฐ์ ์ฌ์ฌ์ฉ
- useCallback์ ํน์ ํจ์๋ฅผ ์๋ก ๋ง๋ค์ง ์๊ณ ์ฌ์ฌ์ฉํ๊ณ ์ถ์ ๋ ์ฌ์ฉ
์ด์ ์ App.js ์์ ๊ตฌํํ๋ onCreate, onRemove, onToggle ํจ์๋ฅผ ํ์ธํด๋ณด์
const onCreate = () => {
const user = {
id: nextId.current,
username,
email
};
setUsers(users.concat(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
)
);
};
- ์ด ํจ์๋ค์ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง ๋ ๋๋ง๋ค ์๋ก ๋ง๋ค์ด์ง๋ค.
- ์ฌ์ค, ํจ์๋ฅผ ์ ์ธํ๋ ๊ฒ ์์ฒด๋ ์ฌ์ค ๋ฉ๋ชจ๋ฆฌ๋, CPU๋ ๋ฆฌ์์ค๋ฅผ ๋ง์ด ์ฐจ์ง ํ๋ ์์ ์ ์๋๊ธฐ ๋๋ฌธ์ ํจ์๋ฅผ ์๋ก ์ ์ธํ๋ค๊ณ ํด์ ๊ทธ ์์ฒด๋ง์ผ๋ก ํฐ ํ๊ฐํ ์๊ธธ ์ผ์ ์์ง๋ง, ํจ์๋ฅผ ํ์ํ ๋๋ง ๋ง๋ค๊ณ ์ฌ์ฌ์ฉํ๋ ๊ฒ์ ์ฌ์ ํ ์ค์ํ๋ค.
- ๋์ค์ ์ปดํฌ๋ํธ์์ props๊ฐ ๋ฐ๋์ง ์์์ผ๋ฉด Virtual DOM์ ์๋ก ๋ ๋๋ง ํ๋ ๊ฒ ์กฐ์ฐจ ํ์ง ์๊ณ ์ปดํฌ๋ํธ์ ๊ฒฐ๊ณผ๋ฌผ์ ์ฌ์ฌ์ฉํ๋ ์ต์ ํ ์์ ์ ํ๋ ค๋ฉด ํจ์๋ฅผ ์ฌ์ฌ์ฉํ๋ ๊ฒ์ด ํ์์ด๋ค!
useCallback์ ์ฌ์ฉํด๋ณด์!
App.js
import React,{useRef, useState, useMemo, useCallback} from 'react'; // useCallback ๋ถ๋ฌ์ค๊ธฐ
import UserList from './UserList';
import CreateUser from './CreateUser';
function countActiveUsers(users){
console.log('ํ์ฑ ์ฌ์ฉ์ ์๋ฅผ ์ธ๋ ์ค...');
return users.filter(user => user.active).length;
}
function App() {
const [inputs, setInputs] = useState({
username: '', email: ''
})
const {username, email} = inputs;
// useCallback์ผ๋ก ํจ์ ์ฌ์ฌ์ฉ
const onChange = useCallback ( e => {
const {name, value} = e.target;
setInputs({
...inputs,
[name]: value
})
}, [inputs]
);
const [users, setUsers] = useState(
[
{id: 1, username: 'John', email: 'john@example.com',
active: true,
},
{id: 2, username: 'Car', email: 'car@example.com',
active: false,
},
{id: 3, username: 'lee', email: 'lee@example.com',
active: false,
},
]
)
const nextId = useRef(4);
// useCallback์ผ๋ก ํจ์ ์ฌ์ฌ์ฉ
const onCreate = useCallback(() => {
const user = {
id: nextId.current,
username,
email
};
setUsers(users.concat(user));
setInputs({
username: '',
email: ''
})
nextId.current += 1;
},[users, username, email]);
// useCallback์ผ๋ก ํจ์ ์ฌ์ฌ์ฉ
const onRemove = useCallback(id => {
setUsers(users.filter(user => user.id !== id))
},[users]);
const onToggle = useCallback(id => {
setUsers(
users.map(user =>
user.id === id ? { ...user, active: !user.active} : user
)
)
},[users])
// useMemo ์ฌ์ฉ
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;
๐ซ ์ฃผ์! ํจ์์์์ ์ฌ์ฉํ๋ ์ํ ํน์ props๊ฐ ์๋ค๋ฉด ๊ผญ, deps ๋ฐฐ์ด์์ ํฌํจ์์ผ์ผ ๋๋ค๋ ๊ฒ์ด๋ค.
- ๊ฐ์ ๋ฃ์ง ์๊ฒ ๋๋ค๋ฉด, ํจ์ ๋ด์์ ํด๋น ๊ฐ์ ์ฐธ์กฐํ ๋ ๊ฐ์ฅ ์ต์ ๊ฐ์ ์ฐธ์กฐํ ๊ฒ์ด๋ผ๊ณ ๋ณด์ฅ ํ ์ ์๋ค!