귀여운 눈높이에서 작성된, 🐰

하루 한 걸음씩, 성장 하는 중 입니다 🫶🏻

Studying/React

리액트 공부하기 - 상태변경 특징 (얕은복사, 깊은복사, 스프레드 연산자, 배열)

creamymood 2025. 4. 9. 00:07

리액트 .. 어렵네..  ㅎr..... 


React의 상태는 불변(immutable)해야 합니다.

React의 상태를 잘 관리하기 위해서는 반드시 기억해야 할 것이 있습니다.

바로, React의 상태는 불변해야 한다는 것입니다. 그 이유는 React가 컴포넌트의 상태가 변경될 때마다 렌더링을 다시 수행하고,

이를 통해 새로운 가상 돔 트리를 구성하는 방식으로 동작하기 때문입니다.

상태의 불변성을 유지할 경우 이전 상태와 새로운 상태 간의 차이를 명확하게 비교할 수 있게 됩니다.

따라서 보다 효율적인 업데이트와 렌더링이 이루어집니다.

반면 상태를 직접 변경하는 경우, 변경사항을 올바르게 감지하지 못할 수 있습니다. 이는 많은 버그의 원인이 되기도 합니다.

 


1. 상태를 변경할 때 그냥 변경하는 것이 아닌,

1. 상태 함수를 사용해야 하고

2. 새로운 상태 값이, 기존 상태 값과 달라야함 !

 

(* 기존과 상태 값이 같다면 상태 값이 업데이트 되지 않았으니, 화면이 재렌더링 되지 않는다.)

 

 

2. 그렇다면, 어떻게 달라진지 판단할 수 있을까 ? 

: 자바스크립트에서 사용하는 데이터 타입에 따라 조금씩 달라진다.

원시 자료형참조자료형에 따라 조금 상이함!

 

2-1 : 원시 자료형은 불변하는 단순 데이터로, 변수에 값 자체를 저장

2-2 : 참조 자료형은 가변하는 복잡한 데이터, 변수에 데이터 그 자체가 아닌 데이터가 담긴 메모리 주소를 저장

 

 

아래사진으로 데이터 타입에 따른 차이를 살펴 보자.

 

 

 

위 사진은, 원시 자료형의 경우 내용이 같다면 같은 값이라 판단되지만

                참조 자료형의 경우 내용이 같아도, 참조형은 주소를 참조하기 때문에, 다른 값이라 판단 된다.

 

 

 

따라서 위 사진과 같은 맥락으로,

 

리액트는 상태값이 기존이랑 같다면, 같다고 판단해서 불필요한 리렌더링을 막아주고 있지만

참조 자료형은 이런 특성을 이해하지 않으면, 똑같은 값을 전달해도 주소가 다르기 때문에 상태가 다르다고 판단해서 리렌더링이 될 수 있기 때문에 주의가 필요하다.

 

기존 상태를 "그냥" 복사해서 가공 한다면 자료형 주소 자체는 바뀌지 않기 때문에, 상태가 바뀌지 않았다고 판단되기에 리렌더링 발생X

= 기존 상태 그냥 복사시 , 주소 그대로 -> 리렌더링 X


그러면 리렌더링 시키고 싶을 땐 ? 

= 그렇다면, 기존 상태를 재 사용하면서, 주소값을 바꾸려면? = 즉, 내용은 같지만 새로운 객체를 만들고 싶다면 ?
spread 연산자, Object.assign, 또는 JSON.parse(JSON.stringify(...)) 같은 걸 써서 깊은 복사 or 얕은 복사로 새 객체나 배열을 만들면, 
주소가 바뀐다 ! 

 

 

예시로써 살펴보자.

const oldArray = [1, 2, 3];

// oldArray의 값을 재사용하지만, 새로운 주소값을 가지도록 새 배열 생성
const newArray = [...oldArray];

 

- 이렇게 하면 newArray는 값은 [1, 2, 3]로 같지만, 주소는 다르니까 리액트는 "이건 새로운 상태네~" 하고 리렌더링한다.

 

즉, **"기존 상태를 재사용하면서, 주소값을 바꾸는 방법"**은

spread 연산자, Object.assign, 또는 JSON.parse(JSON.stringify(...)) 같은 걸 써서

깊은 복사 or 얕은 복사로 새 객체나 배열을 만드는 걸 말한다.

 

 

 

그러다가, 궁금해진 내 머리.. 지피티 ㅠ 짜증내서 미안해 ㅠㅠ

 

상냥한 GPT: 지금 딱 핵심 찔렀어! 👀 좋아, 정확히 뭐가 다른지 아주 쉽게 설명해줄게!

저런 복사는, 주소값이 같은 복사다.

 


✓ 그럼 리렌더링 되게 하려면?

예시 1: 배열 값 바꾸기 (주소도 바뀜)

setMyArray([...myArray, 4]);  // 값 바뀜 + 주소도 바뀜 ➡️ ✅ 리렌더링됨

 

 예시 2: 직접 수정 (❌ 권장 안 함)

myArray.push(4);
setMyArray(myArray);  // 값은 바뀌었지만 주소는 그대로 ➡️ ❌ 리렌더링 안 됨

 

그래서 배열 수정할 때는 push 대신에 spread를 쓰는 것.

 

setMyArray([...myArray, 4]);

 

 


출처 : 챗지피티, 구글링, 오즈코딩스쿨 학습 자료