코드도보통지

5관문. Object Identity

관문 5 / 7

중첩 객체를 불변성을 지키며 업데이트하고, Immer 패턴의 편의성을 체험하라.

📖 이론 비급

Object Identity: 불변성과 참조 무결성

리액트는 상태 변경을 참조 비교로 감지한다. state.user.name = 'Kim'처럼 직접 변경하면 참조가 같아 리렌더가 발생하지 않는다.

해결책: 스프레드 연산자로 새 참조를 만들어야 한다. setState(prev => ({ ...prev, user: { ...prev.user, name: 'Kim' } })) 중첩이 깊어지면 immer의 produce()를 활용하면 마치 직접 수정하는 듯한 문법으로 불변 업데이트가 가능하다.

⚔️ 수련 코드

import { useState } from 'react';

export default function ProfileEditor() {
  const [user, setUser] = useState({
    name: '홍길동',
    address: {
      city: '서울',
      district: '강남구',
    },
  });

  function handleCityChange(newCity) {
    // 문제: 직접 변경은 리렌더를 보장하지 않는다
    user.address.city = newCity;
    setUser(user);
  }

  return (
    <div>
      <p>{user.name} - {user.address.city} {user.address.district}</p>
      <button onClick={() => handleCityChange('부산')}>
        도시 변경
      </button>
    </div>
  );
}