이롭게 현명하게
[React] 리액트 useCallback 본문
목차
useCallback이란?
import
예시 코드
정리
[useCallback이란?]
useCallback은 useMemo와 비슷하다.
useMemo : 특정 결괏값을 재사용할 때 사용
useCallback : 특정 함수를 새로 만들지 않고 새로 사용
useCallback을 사용하지 않는 함수들은 컴포넌트가 리렌더링 될 때마다 새로 만들어진다.
함수를 새로 만드는 것은 메모리, cpu가 리소스를 많이 차지하지는 것은 아니다.
함수를 새로 선언한다고 해서 그 자체만으로 큰 부하가 생기지 않는다.
한번 만든 함수를 재사용할 수 있을 때 재사용하는 것이 좋다.
나중에 컴포넌트들이 props가 바뀌지 않는다면 Virtual DOM에 리렌더링 조차 안 하게 할 수 있다.
만약 props가 바뀌지 않았다면 Virtual DOM을 새로 그리는 것이 아닌 이전에 만들어 뒀던 결과물을 재사용할 수 있다.
그 작업을 하려면 매번 함수가 새로 만들어지는 구조라면 최적화할 수 있다.
그러므로 함수도 재사용해 줘야 한다.
[import]
import React,{useCallback} from "react";
<형태>
const 변수명 = useCallback(()=>{수행해야할 문장},[deps 배열]);
deps 값을 넣지 않는다면 함수 내부에서 해당 상태들을 참조하게 될 때 가장 최신 상태를 참조하는 것이 아닌 이전의 것. 즉, 컴포넌트가 처음 만들어질 때인 예전 상태를 참조하게 된다.
useCallback 내부에서 참조하게 되는 상태 혹은 props로 받아오는 어떤 값이 있다면 넣어줘야 한다.
[예시 코드]
// 전체 코드
// App.js //
import React,{useRef,useState,useMemo,useCallback} from "react";
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;
const onChange = useCallback(e =>{
const {name,value} = e.target
setInputs({
...inputs,
[name]:value
});
},[inputs]);
const [users,setUsers] =useState([
{
id : 1,
username : 'uni',
email : 'uni@gmail.com',
active : true
},
{
id : 2,
username : 'dog',
email : 'dog@gmail.com',
active : false
},
{
id : 3,
username : 'cat',
email : 'cat@gmail.com',
active : false
}
]);
const nextId = useRef(4);
const onCreate = useCallback(() =>{
const user = {
id: nextId.current,
username,
email
}
setUsers(users.concat(user));
setInputs({
username:'',
email:''
});
//console.log(nextId.current)
nextId.current +=1;
console.log(users)
},[username,email,users]);
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);
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;
// CreateUser.js //
import React from "react";
function CreateUser({username,email,onChange,onCreate}){
return(
<div>
<input name="username" placeholder="계정명" onChange={onChange} value={username}/>
<input name="email" placeholder="이메일" onChange={onChange} value={email}/>
<button onClick={onCreate}>등록</button>
</div>
);
}
export default CreateUser;
// UserList.js //
import React,{useEffect} from "react";
function User({user, onRemove,onToggle}){
const {username,email,id,active}=user;
return(
<div>
<b
style={{
color: active? 'green': 'black',
cursor : 'pointer'
}}
onClick={()=>onToggle(id)}
>{user.username}</b> <span>{user.email}</span>
<button onClick={()=>onRemove(user.id)}>삭제</button>
</div>
);
}
function UserList({users,onRemove,onToggle}){
return(
<div>
{
users.map(
user =>(<User user={user} key={user.id} onRemove={onRemove} onToggle={onToggle}/>)
)
}
</div>
);
}
export default UserList;
const onChange = useCallback(e =>{
const {name,value} = e.target
setInputs({
...inputs,
[name]:value
});
},[inputs]);
[inputs] : 내부에서 의존하고 있는 값. deps값
useState를 통해 inputs를 관리하고 있다.
onChange 함수는 inputs가 바뀔 때만 함수가 새로 만들어지고 그렇지 않다면 기존에 만든 함수를 재사용하게 된다.
[정리]
import React,{useCallback} from "react";
const 변수명 = useCallback(()=>{수행해야할 문장},[deps 배열]);
useCallback : 특정 함수 재사용
useMemo : 특정 결괏값 재사용
컴포넌트에서 props가 바뀌지 않았으며 Virtual DOM에 새로 렌더링 하는 것조차 하지 않고 컴포넌트의 결과물을 재사용하는 최적화 작업을 하려면 함수 재사용 필수
deps 배열에 꼭 포함되어야 하는 것 : 함수 안에서 사용하는 state혹은 props
컴포넌트 렌더링 최적화 작업을 해주어야만 성능이 최적화 : useCallback & React.memo
잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊
댓글과 좋아요는 큰 힘이 됩니다!
'웹 개발 > React' 카테고리의 다른 글
[React] 리액트 useReducer (0) | 2024.01.18 |
---|---|
[React] 리액트 React.memo (0) | 2024.01.17 |
[React] 리액트 State란? (0) | 2024.01.15 |
[React] 리액트 props 사용방법 (0) | 2024.01.12 |
[React] 컴포넌트(Component) 만들기 (2) | 2024.01.11 |