useMemo는 컴포넌트 리렌더링 간에 계산 결과를 캐싱할 수 있는 Hook(훅)이다. 
그래서 성능상의 이유로만 사용되며, useCallback, 디바운싱, 동시 렌더링 등과 같은 기술과 함께 사용해야 한다. 이 훅은 일부 상황에서는 굉장히 도움이 되지만, 대부분의 개발자가 적절하게 사용하지 못하고 있다.
메모이제이션(memoization)은 대가 없이 제공되지 않는다.
하지만 그들은 최적화가 되기를 바라며, 모든 변수를 useMemo로 감싼다. 이 방법은 그저 가독성이 떨어지고 메모리 사용량을 증가할 뿐이다.
메모이제이션, 개념만 보았을 때는 굉장히 효율적이고 사용하기만 하면 최적화가 이루어질 것 같은 느낌이 들기도 합니다. 하지만 명확한 목적없이 무작정 메모이제이션을 사용하는 것은 오히려 비효율적입니다.
새로운 값을 만드는 것과어딘가에 이전의 값을 저장해두고 메모이제이션 함수를 호출하고 의존성을 비교해서 가져올지 말지 여부를 판단하는 것중 어떤 것이 비용이 더 적게 들까?
위의 문장에 대한 정답은 상황에 따라 다릅니다.
만약 새로운 값을 만드는 과정이 복잡하다면 메모이제이션을 사용하는 것이 더 효율적일 수 있습니다. 하지만 새로운 값을 만드는 과정이 복잡하지 않다면 메모이제이션을 사용하는 것은 오히려 비용이 더 많이 들수도 있습니다. 컴퓨터 자원의 측면뿐만 아니라 메모이제이션을 쓰면서 코드의 복잡도가 올라간다는 개발적인 측면의 비용도 무시할 수 없습니다.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
useMemo는 두가지 인자를 받습니다. 
메모이제이션을 할 때 주의해야 할 점은 만약 새로운 값을 만들어서 사용해야 하는 상황임에도 불구하고 이전의 결과를 그대로 활용해버리면 버그가 발생할 수 있다는 점입니다.
위의 예시에서 a, b 라는 두가지 변수를 이용해서 메모이제이션 하기 위한 값을 계산하고 있습니다. 그런데 만약 a, b 라는 값이 변경되었는데 이전의 값을 그대로 활용해버리면 의도한 결과와 다른 결과가 나오게 될 것입니다.
이런 상황을 방지하기 위해서 useMemo에서는 의존성 배열을 인자로 받아, 의존성 배열에 있는 값 중 하나라도 이전 렌더링과 비교했을 때 변경되었다면 메모된 값을 활용하는 것이 아니라 새로운 값을 다시 계산합니다.