Joonas' Note
[React] useDeepMemo 본문
- 참고
primitive 하게 비교되지 않는 object들은 의존성 배열에서 같은 값으로 인식하지 않는다.
이건 javascript 의 비교 연산자가 얕은 비교를 하기 때문이다. 아래는 대표적인 사례.
{} == {}
// output: false
즉, 아래의 memo는 전혀 캐싱되지 않기 때문에 어떤 스노우볼을 굴릴 지 모른다.
const complexObject = {a:1, b:2, c:"xyz"}
// 의존성 배열은 항상 다른 값으로 인식된다.
const complexMemo = useMemo(() => complexObject, [complextObject])
아래와 같이 비교 대상을 문자열로 변경해서 해결하는 방법도 있는데, 보기에도 느껴지지만 그렇게 권장되는 방법은 아니다.
const complexObject = {a:1, b:2, c:"xyz"}
const complexMemo = useMemo(() => complexObject, [JSON.stringify(complextObject)])
위 방법과 크게 다르지 않지만, 핵심은 의존성 배열 내의 객체를 비교해야 하는 것이므로, 구조적으로 변경할 수 있게 아래처럼 작성해서 사용하고 있다.
// useDeepHooks.ts
import { useRef, useEffect, useMemo } from 'react'
const serialize = (obj: any) => {
if (typeof obj === 'object') {
return JSON.stringify(obj)
}
return obj
}
export function useDeepMemo(callback: () => any, dependencies: any[]) {
const depsStringified = useMemo(
() => dependencies.map(serialize),
dependencies,
)
return useMemo(() => callback(), depsStringified)
}
리액트 개발자 중 한 명은 이 외에도 2가지 방법을 더 제시하고 있다.
그 외에도 ref 를 사용해서 상태를 들고 있는 방법도 있는데, Object 비교에서 실수한건지 제대로 동작하진 않았다.
참고
When to useMemo and useCallback
Stay up to date Stay up to date All rights reserved © Kent C. Dodds 2025
kentcdodds.com
useCallback/useEffect support custom comparator · Issue #14476 · facebook/react
Currently we can pass an array as second argument when using useCallback or useEffect like below: useCallback(()=> { doSth(a, b) }, [a, b]) // how to do deep equal if a is an object ? The problem i...
github.com
'개발 > Javascript' 카테고리의 다른 글
FormData 전송할 때 fetch vs. axios (0) | 2025.04.16 |
---|---|
사과 게임 헬퍼 만들어보기 (0) | 2025.03.09 |
[Browser] pageX/screenX/clientX/offsetX 비교 (0) | 2024.08.26 |
블로그 포스트 읽는 시간 예측하기 (0) | 2024.02.07 |
눈코입 맞추기 게임 만들기 3편 (3) | 2024.01.20 |