본문 바로가기

리액트 공식 문서 읽기

14화: Updating Objects in State

이 글은 단순히 리액트 공식 문서를 읽고 베꼈을 뿐이다!! 학습 목적이라면 공식 문서를 보는 걸 추천한다.

 

참새.   Unsplash 에 Carlos Quintero 님이 올림

공식 문서

https://react.dev/learn/updating-objects-in-state

 

Updating Objects in State – React

The library for web and native user interfaces

react.dev

교체(replacement)와 변형(mutation)

// replace
const [position, setPosition] = useState({ x: 0, y: 0 });
setPosition({ x: 7, y: 0 });

// mutate
const [position, setPosition] = useState({ x: 0, y: 0 });
position.x = 7;
  • 교체는 아예 새로운 값으로 바꾸는 것
  • 변형은 기존 값의 내부 내용물을 바꾸는 것
  • 리액트 상태로 객체를 사용할 경우 이론상 변형이 가능하지만, 불가능한 것처럼 다룰 것
  • 객체의 일부만 바꾸고 싶더라도 교체를 사용할 것

상태는 읽기 전용으로 다루기

  • 상태로 사용되는 모든 자바스크립트 객체는 읽기 전용으로 다루기
  • 렌더링에서 사용하는 객체는 snapshot -> 이걸 직접 바꾸더라도 리액트가 바뀐 걸 몰라서 리렌더링 안함
  • 리렌더링을 하고 싶으면 새로운 객체를 만들어서 상태 설정 함수에게 주면 됨
  • 변형(mutation)이 아예 금지된 게 아님! 상태값으로 주어진 객체를 변형하지 말라는 소리
  • 리액트는 Object.is 를 통해 변화가 있는지 없는지 탐지함. 상태 객체 변형은 메모리 참조가 동일하므로 아무 일도 일어나지 않음

전개(spread) 구문으로 객체 복사하기

// 일반적인 복사
setPerson({
  ...person, // Copy the old fields
  firstName: newFirstName, // But override this one
});

// 동적인 속성은 이렇게 가능
setPerson({
  ...person,
  [name]: newName,
});
  • 전개 구문은 얕은 복사임을 기억하기
  • 동적 속성을 나타내고 싶을 때는 대괄호 사용 가능

중첩된 객체 상태 바꾸기

  • 내부 객체뿐 아니라 외부의 객체들도 바꿔줘야 함
  • 객체가 중첩된 것처럼 보여도 결국 포인터처럼 주소를 가리키는 것에 가까우므로 항상 주의할 것
  • 중첩이 너무 심하면 flatten을 고려해 볼 것
  • 그럼에도 불구하고 다중 중첩 객체를 써야 한다면 Immer 같은 라이브러리를 고려해 볼 것 (Immer는 내부적으로 Proxy 객체를 활용해서 변화를 탐지함)

리액트에서 상태 변형을 하면 안 되는 이유들

  • 디버깅에 용이함
  • 최적화: 리액트 최적화 전략들은 이전 props나 상태가 다음과 동일한지 비교하는 작업에 의존함. 변형을 아예 하지 않는다면 이런 작업은 쉬움
  • 새로운 기능: 리액트의 새로운 기능들은 상태 변수가 snapshot이라는 가정 하에 만들어짐
  • 요구사항 변화: 개발할 때 과거 상태를 기억해야 하는 요구사항이 갑자기 생길 때 코드를 고치기 쉬움
  • 쉬운 구현 난이도: 우리는 객체를 변형할 필요 없이 그냥 무지성으로 새로 만들어서 쓰면 됨

'리액트 공식 문서 읽기' 카테고리의 다른 글

16화: Reacting to Input with State  (0) 2023.06.16
15화: Updating Arrays in State  (0) 2023.06.16
13화: Queueing a Series of State Updates  (0) 2023.06.15
12화: State as a Snapshot  (0) 2023.06.15
11화: Render and Commit  (0) 2023.06.15