react

react useMemo, useCallback

deadeye 2023. 3. 20. 14:07

 

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 호출하는 경우