Deep Copy VS Shallow Copy

seohyun Kang·2023년 6월 13일
0

Javascript

목록 보기
2/3

Introduction

이전에 React에서 Shallow Copy로 인해 객체 참조 주소가 변경되지 않아서 React에서 Re-render가 되지 않는 이슈를 정리한적이 있습니다.

당시에는 String 배열과 같은 경우 [...arr] 과 같은 방식을 통해서 새로운 주소를 갖는 배열을 생성하여 setState하는 것으로 문제를 해결했었습니다.

Review

const refCopy = () => {
	const temp = arrayState;
    temp[1] = "NEW";
    console.log(temp, arrayState);
    setArrayState(temp);
}

> 
["1", "NEW"] 
["1", "NEW"]

* Reference Copy : Not Re-rendered

const refCopy = () => {
	const temp = [...arrayState];
    temp[1] = "NEW";
    console.log(temp, arrayState);
    setArrayState(temp);
}

> 
["1", "NEW"] ["1", "2"]

* Shallow Copy : Re-rendered

Problem

String[] || Number[]가 아닌 Object[]와 같은 경우는 어떨까?

사실 Object[] 형식도 Shallow Copy를 통해 참조값의 주소를 변경하기 때문에, Re-render 과정에서는 문제가 발생하지 않는다. 다만, 아래와 같이 arrayState 배열 안의 객체도 같이 변경되는 문제가 발생한다.

Reference Copy : 

	const temp = arrayState;
    temp[1].text = "NEW";
    console.log(temp, arrayState);
    setArrayState(temp);
    
> 
[{text : "1"}, {text : "NEW"}] 
[{text : "1"}, {text : "NEW"}]

Shallow Copy :

	const temp = [...arrayState];
    temp[1] = "NEW";
    console.log(temp, arrayState);
    setArrayState(temp);
    
> 
[{text : "1"}, {text : "NEW"}] 
[{text : "1"}, {text : "NEW"}]

왜 이런 문제가 발생하는걸까?

원인은 배열 안의 객체 또한 참조값이기 때문이다.

Shallow Copy는 객체의 비트 단위 복사본이고 모든 데이터와 참조값은 복사되어 새로운 객체에 할당 (실제 데이터를 가르키는 새 데이터가 생성) 됩니다.

그러나 얕은 복사에서는 참조도 복사됩니다. 즉, 개체 내부의 모든 참조 개체는 여전히 원래 개체와 동일한 개체를 가리킵니다.

Deep Copy

이와 같이, 배열 혹은 객체로 감싸진 어떤 값에 대해서 수정하기 위해 Deep Copy를 사용하게 된다.

Deep Copy는 모든 참조 객체와 함께 모든 데이터 멤버를 재귀적으로 복제합니다. 따라서 참조용으로 새 객체도 생성됩니다. 이 프로세스는 재귀적입니다. 즉, 참조 객체에 다른 참조가 포함되어 있으면 해당 객체에 대한 새 객체도 생성됩니다.

Javascript에서는 structuredClone이라는 메소드를 통해 Deep Copy를 지원하고 있습니다.

Deep Copy :

	const temp = structuredClone(arrayState);
    temp[1].text = "NEW";
    console.log(temp, arrayState);
    setArrayState(temp);
    
> 
[{text : "1"}, {text : "NEW"}] 
[{text : "1"}, {text : "2"}]

Conclusion

Stackoverflow에서 Shallow Copy와 관련된 이슈에 대해서 코멘트를 작성 중에 structuredClone이라는 메소드를 알게 되었고, Deep Copy에 대해서 정리하는 계기가 되었습니다.

새 주소로 할당된 객체의 값이 참조값일 경우 여전히 동일한 원본 주소를 가진다는 것을 이해하게 되었고 이 부분과 관련해서 이해할 수 있는 좋은 경험이었습니다.


Reference:
Shallow & Deep Copy

0개의 댓글