Object.is(): React Hooks의 핵심

DongHyun Park·2024년 10월 9일
1

React

목록 보기
4/6
post-thumbnail

React의 useEffect()와 useMemo() Hooks를 살펴보면서, 우리는 의존성 배열의 변화를 감지하는 areHookInputsEqual 함수를 발견했습니다. 이 함수의 핵심에는 Object.is() 메서드가 있었죠. 이 흥미로운 발견을 통해 우리는 JavaScript에서의 정확한 동등 비교가 얼마나 중요한지 알 수 있었습니다. 그렇다면 이 Object.is() 메서드에 대해 더 자세히 알아볼까요?

목차

  1. React Hooks와 Object.is()의 연결
  2. Object.is()란?
  3. Object.is()와 다른 비교 연산자의 차이
  4. Object.is()의 동작 방식
  5. true를 반환하는 경우
  6. false를 반환하는 경우
  7. 특별한 경우: NaN과 ±0
  8. Object.is()의 실제 사용 사례
  9. 결론

React Hooks와 Object.is()의 연결

useEffect와 useMemo에서 사용되는 areHookInputsEqual 함수를 다시 한번 살펴봅시다:

function areHookInputsEqual(
  nextDeps: Array<mixed>,
  prevDeps: Array<mixed> | null,
) {
  if (prevDeps === null) {
    return false;
  }
  for (let i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
    if (Object.is(nextDeps[i], prevDeps[i])) {
      continue;
    }
    return false;
  }
  return true;
}

여기서 우리는 Object.is()가 의존성 배열의 각 요소를 비교하는 데 사용되는 것을 볼 수 있습니다. 그렇다면 이 Object.is()는 정확히 무엇이고, 왜 React는 이를 선택했을까요?

Object.is()란?

Object.is()는 ECMAScript 6에서 도입된 메서드로, 두 값이 같은지 판단합니다. 이 메서드는 === (엄격한 동등 연산자)와 유사하지만, 몇 가지 특별한 경우에 다른 결과를 반환합니다.

Object.is()와 다른 비교 연산자의 차이

  1. == (동등 연산자): 타입 강제 변환을 수행합니다.
  2. === (일치 연산자): 타입 강제 변환을 수행하지 않습니다.
  3. Object.is(): ===와 유사하지만 NaN±0을 처리하는 방식이 다릅니다.

Object.is()의 동작 방식

Object.is(value1, value2)는 다음과 같은 알고리즘으로 동작합니다:

  1. 두 값이 모두 undefined이면 true를 반환합니다.
  2. 두 값이 모두 null이면 true를 반환합니다.
  3. 두 값이 모두 true 또는 모두 false이면 true를 반환합니다.
  4. 두 값이 모두 같은 문자열이면 true를 반환합니다.
  5. 두 값이 모두 같은 숫자이면 true를 반환합니다.
    • 둘 다 +0이면 true를 반환합니다.
    • 둘 다 -0이면 true를 반환합니다.
    • 둘 다 NaN이면 true를 반환합니다.
  6. 두 값이 모두 같은 객체를 참조하면 true를 반환합니다.
  7. 그 외의 모든 경우에 false를 반환합니다.

true를 반환하는 경우

// 기본 타입
Object.is(undefined, undefined);  // true
Object.is(null, null);            // true
Object.is(true, true);            // true
Object.is(false, false);          // true
Object.is('hello', 'hello');      // true
Object.is(42, 42);                // true
Object.is(NaN, NaN);              // true

// 객체
const obj = { a: 1 };
Object.is(obj, obj);              // true

// 특별한 경우
Object.is(0, 0);                  // true
Object.is(-0, -0);                // true

false를 반환하는 경우

// 다른 타입
Object.is(42, '42');              // false
Object.is(true, 1);               // false
Object.is(null, undefined);       // false

// 다른 값
Object.is('hello', 'world');      // false
Object.is(42, 43);                // false

// 객체
Object.is({}, {});                // false
Object.is([], []);                // false

// 특별한 경우
Object.is(0, -0);                 // false

특별한 경우: NaN과 ±0

Object.is()NaN±0을 처리하는 방식에서 ===와 다릅니다:

// NaN
Object.is(NaN, NaN);              // true
NaN === NaN;                      // false

// +0과 -0
Object.is(0, -0);                 // false
0 === -0;                         // true

이러한 차이는 특정 수학적 연산이나 정밀한 비교가 필요한 경우에 중요할 수 있습니다.

Object.is()의 실제 사용 사례

  1. React의 useEffect와 useMemo: 의존성 배열의 변화를 감지할 때 사용됩니다.
useEffect(() => {
  // 부수 효과
}, [dependency]);  // 여기서 dependency의 변화를 Object.is()로 감지
  1. 정밀한 수학 연산: +0-0을 구분해야 하는 경우에 유용합니다.
function divideByZero(x) {
  const result = x / 0;
  if (Object.is(result, Infinity)) {
    return "양의 무한대";
  } else if (Object.is(result, -Infinity)) {
    return "음의 무한대";
  }
}
  1. NaN 체크: NaN을 정확히 비교해야 할 때 사용합니다.
function isNaN(value) {
  return Object.is(value, NaN);
}

결론

React Hooks의 내부 구현을 통해 발견한 Object.is()는 JavaScript에서 가장 엄격하고 정확한 동등 비교 방법을 제공합니다. 특히 NaN±0의 비교에서 독특한 특성을 보여주며, 이는 React와 같은 라이브러리에서 정확한 상태 비교를 위해 중요합니다.

개발자로서 우리는 이러한 미묘한 차이를 이해하고, 상황에 따라 적절한 비교 방법을 선택해야 합니다. Object.is()의 특성을 잘 이해하고 활용한다면, React 애플리케이션뿐만 아니라 일반적인 JavaScript 프로그래밍에서도 더욱 정확하고 예측 가능한 코드를 작성할 수 있을 것입니다.

0개의 댓글