react useMemo, useCallback
- 벨로퍼트 react 실습임
- 해당컴포넌트의 정보가 필요할시
- https://react.vlpt.us/basic/17-useMemo.html
useMemo : 리액트에서 컴포넌트의 성능을 최적화 하는데 사용되는 훅(Memo : memoization)
리액트에서 함수형 컴포넌트는
랜더링 -> 컴포넌트 함수 호출 -> 모든 내부 변수 초기화의 순서를 거침
일반 함수를 호출할때 특정 행위에만 바꾸고 싶은데 다른 행위에도 컴포넌트가 리렌더링 되어 함수가 호출 되기 때문에 자원이 낭비됨
그렇기 때문에 등장한 useMemo
일반적인 함수 호출
function countActiveUsers(users){
console.log('활성 사용자 수를 세는중...');
return users.filter(user=>user.active).length
}
function App(){
const count = countActiveUsers(users);
return (
<UserList users={users} onRemove={onRemove} onToggle={onToggle} />
<CreateUser
username={username}
email={email}
onChange={onChange}
onCreate={onCreate}
/>
<div>활성사용자 수 : {count}</div>
</div>
);
}
위 코드를 실행하면 사용자를 활성화 시키지 않고 input에 값을 변화한것만으로도 console 즉 countActiveUsers(users)가 실행됨.
내가 원할때만 함수를 실행하므로 불필요한 메모리 소모가 일어난다는 뜻 임 ㅇㅇ
그럼 이제 우리는 불필요한 메모리 소모를 없애기 위해 코드를 살짝 바꿔보는데
useMemo는 첫번째 파라미터에 함수를 넣고 두번째 파라미터에는 deps배열을 넣으면됨
function countActiveUsers(users){
console.log('활성 사용자 수를 세는중...');
return users.filter(user=>user.active).length
}
function App(){
const count = useMemo(()=>countActiveUsers(users),[users]);
return (
<UserList users={users} onRemove={onRemove} onToggle={onToggle} />
<CreateUser
username={username}
email={email}
onChange={onChange}
onCreate={onCreate}
/>
<div>활성사용자 수 : {count}</div>
</div>
);
}
이렇게 해보면 계정 active바뀔때만 생성되고 Input수정시는 실행안됨
useCallback
useMemo 는 특정 결과값을 재사용 할 때 사용하는 반면, useCallback 은 특정 함수를 새로 만들지 않고 재사용하고 싶을때 사용합니다.
자세한 코드는
https://react.vlpt.us/basic/18-useCallback.html -> 참고할 것
* 주의 하실 점은, 함수 안에서 사용하는 상태 혹은 props 가 있다면 꼭, deps 배열안에 포함시켜야 된다는 것 입니다. 만약에 deps 배열 안에 함수에서 사용하는 값을 넣지 않게 된다면, 함수 내에서 해당 값들을 참조할때 가장 최신 값을 참조 할 것이라고 보장 할 수 없습니다
비슷하지만 다른 useMemo useCallback
const onToggle = useCallback(
id => {
setUsers(
users.map(user =>
user.id === id ? { ...user, active: !user.active } : user
)
);
},
[users]
);
const count = useMemo(()=>countActiveUsers(users),[users]);
useMemo -> deps값이 변하면 이 함수를 실행
useCallback
1) 자식 컴포넌트에 props로 함수를 전달할 경우
2) 외부에서 값을 가져오는 api를 호출하는 경우