그렇다면 어떻게 복사를 해야 이런 오류를 막을 수 있을까?
결론부터 말하자면 **객체 복사라는 것은 존재하지 않는다.**
**원본 객체와 같은 값을 가진 객체를 새로 만들 수 있을 뿐**
이다.
따라서 객체를 복사한다고 하지만, 아래 코드처럼 child2 객체의 각 값을 꺼내서 child3의 각 key에 할당함으로써 복사한 것과 같은 모습이되는 것이다.
엄밀히 말하면 복사는 아니지만, 이러한 것을 객체 복사
라고 한다.
이렇게 객체 복사하면 복사본 값을 변경해도 원본의 값이 변경되지 않고 유지된다.
// child3에 child2 복사
let child3 = {
name: child2.name,
age: child2.age,
school: child2.school
}
child3 // {name: '영희', age: 8, school: '다람쥐초등학교'}
소소한 꿀팁
let child2 = {...}
에서 중괄호를 여는 순간 메모리에 주소 저장되는 것이다.
객체가 시작하면 주소가 저장된다고 생각하면 된다.
중괄호를 열고 스프레드 연산자를 통해 값을 넣어주는 것이, 엄밀히 말해 값을 복사하는 것이 아닌 새로운 객체에 새로운 주소에 값을 넣어준 것이다.
객체를 복사할 때 마다 모든 값을 가져오는 것은 번거러운 작업인데 객체에 들어가는 데이터의 양이 많아지면 어떻게 될까?
스프레드 연산자
이다....
을 통해 해당 객체 내의 모든 값을 개별 요소로 분리한다.let child4 = {
...child2
}
child4 // {name: '영희', age: 8, school: '다람쥐초등학교'}
객체 안에 객체가 값으로 들어가 있는 중첩 객체의 경우도 스프레드 연산자로 복사가 가능할까?
결론 먼저 말하면, 객체 안에 객체가 값으로 들어가 있는 경우 제대로 복사가 되지 않는다.
객체 안의 객체 또한 주소가 저장이 되기 때문에 중첩된 객체를 수정하면 그값의 원본값이 변한다.
hobby는 새로운 중괄호를 열고 profile.hobby를 스프레드 해줘야 한다. 그래야 hobby의 메모리 주소를 복사하는 것이 아닌 개별 요소까지 저장할 수 있다.
스프레드를 통해서 하는 복사를 얕은 복사
라고 한다.
객체의 특정key값의 value만 바꿔주는 방법을 이용
즉, 중첩 객체의 key,value를 다시 스프레드를 이용해서 복사해 오는 것 입니다.
const me = {
name : "혜원",
info : {
nickname : "개구리",
mbti : "ENTJ",
position : "프론트엔드"
}
}
const copyMe = {...me,info:{...me.info}}
console.log(copyMe)
//결과
// copyMe = {
// name : "혜원",
// info : {
// nickname : "개구리",
// mbti : "ENTJ",
// position : "프론트엔드"
// }
// }
//깊은 복사가 됐는지 확인해보기
copyMe.info.nickname = "wonny"
console.log(copyMe.info.nickname) // "wonny"
console.log(me.info.nickname) // "개구리"
아까와는 다르게 중첩객체를 복사해올 때 한번 더 스프레드를 이용해서 복사해왔습니다.
이렇게 하게되면 중첩객체 내부의 property또한 깊은 복사가 되게 됩니다.
얕은 복사를 하면 깊이가 어디까지 깊어질지 모르는데 한 번씩 계속해줘야 하면 비효율적이지 않는가
JSON.stringify()
에 넣으면 문자열로 변환해주고 다시JSON.parse()
에 넣으면 문자열을 기존과 다른 새로운 객체로 만들어준다.lodash.cloneDeep()
을 사용하여 깊은 복사를 한다.
call by value
: 데이터의 값, value를 직접 요청한다
call by refernce
: 객체를 복사한 경우처럼 데이터의 주소를 요청한다.
call by reference
와 관련이 있다. 같은 주소를 참조하고 있기 때문
배열을 변경하고 setState에 값을 넣어주었을 때 리렌더 되지 않는 문제는 어떻게 해결할까?
스프레드 해주어야 비로소 qqq와 myIndex가 다른 주소를 갖는 다른 값
이다. 소소한 꿀팁
객체나 배열의 경우 값을 복사나 평소에도 일관적으로 얕은 복사하여 넣어줘야 한다. 프로젝트 규모가 커지면 원본 값이 어떻게 사용되는지 모르기 때문에 프로젝트의 안정성을 위해서 얕은 복사해주는 것이 좋다.
페이지네이션은 10개가 보여지고 다음 10개가 보여질 때 전의 10개는 사라졌었으나,
무한스크롤에서는 10개가 보여지고 다음 10개가 보여질 때 이전의 10개가지 총 20개가 보여지는 것이 포인트
위처럼 해야 map
을 통해서 한번에 전체 댓글을 보여줄 수 있다.
아래에 댓글들을 가져오고 if문을 통해서 다음 페이지에 올 데이터가 없다면 기존에 데이터만 넘겨준다.
variables에는 다음에 받아올 페이지를 넣어준다. (ex. 현재 20개 댓글이 있는 2페이지면 다음엔 3페이지)
스크롤 부분은 라이브러리를 사용하고 라이브러리에서 스크롤이 내려갔을 때 함수를 실행시키는데, 그 때 실행시키는 함수가 fetchMore
이다.