array, object 자료일 경우에 state 수정할 때의 주의해야 할 점에 대해 알아봅시다.
글수정 버튼
지난시간에 코드에서
아래코드를 추가하여 클릭을하면 state를 변경해주는 버튼을 만들었습니다.
function App(){
let [글제목, 글제목변경] = useState( ['남자코트 추천', '강남 우동맛집', '파이썬 독학'] );
return (
<button onClick={ ()=>{
글제목변경(['여자코트 추천', '강남 우동맛집', '파이썬 독학'])
} }> 수정버튼 </button>
)
}
하지만 위의코드는 별로 좋지 않습니다.
만약 []안에 글이 100개가 있으면 onClick안의 코드도 매우 길어지게 됩니다.
그래서 state를 첫 글만 바꿔서 state변경함수에 집어넣는 식으로 바꿔보겠습니다.
function App(){
let [글제목, 글제목변경] = useState( ['남자코트 추천', '강남 우동맛집', '파이썬 독학'] );
return (
<button onClick={ ()=>{
글제목[0] = '여자코트 추천';
글제목변경(글제목)
} }> 수정버튼 </button>
)
}
이렇게 array의 항목을 변경할 수 있습니다.
array의 항목을 변경하고 state변경함수에 집어넣는 방식입니다.
하지만 array, object 자료 다룰 때는 원본 데이터를 직접 조작하는 것 보다는
기존값은 보존해주는 식으로 코드를 작성하는게 좋습니다.
(원본이 필요한 경우가 생길 수 있기 때문에)
그래서 새로운 변수에다가 기존 원본을 복사해놓고 새로운 변수를
조작하는 식으로 코드를 작성하는게 안전합니다.
function App(){
let [글제목, 글제목변경] = useState( ['남자코트 추천', '강남 우동맛집', '파이썬 독학'] );
return (
<button onClick={ ()=>{
let copy = 글제목;
copy[0] = '여자코트 추천';
글제목변경(copy)
} }> 수정버튼 </button>
)
}
위처럼 코드를 작성하고 버튼을 클릭해보면 변경이되지 않습니다.
여기서 state의 동작원리에 대해 알 필요가 있습니다.
state 변경함수 동작원리
state 변경함수를 쓸 때 기존state === 신규 state 이렇게 먼저 검사를 합니다.
그래서 같으면(true)이면 변경을 해주지 않습니다.
그래서 위 코드에서도 글제목변경(copy)를 해도 copy라는 변수가 기존 state와 같아서 변경을 안해준 것입니다.
console.log(글제목1==copy); 실제로 검사를 해보면 아래처럼 true가 나옵니다.
좀더 자세히 살펴보면
array/object 동작원리
- 자바스크립트는 array/object 자료를 하나 만들면 (ex. let arr=[1,2,3]) [1,2,3]자료는 램이라는 가상공간에 몰래 저장이 되고 let arr변수엔 그 자료가 어디있는지 가리키는 화살표만 담고 있습니다.
- 그래서 let data = arr 이렇게 복사하면 data와 arr은 똑같은 값을 공유합니다.( data를 변경하면 arr도 자동으로 변경됩니다 왜냐하면 변수에는 화살표만 저장이 되었기 때문입니다.)
그래서 아래처럼 작성하면 변경이 됩니다.
let copy = [...글제목];
copy[0] = '여자코트 추천';
글제목변경(copy)
spread operator
여기서 점3개는 spread operator라고 하는 문법입니다.
array나 object 자료형 왼쪽에 붙일 수 있으며 괄호를 벗겨주세요 라는 뜻입니다.
...[1,2,3]이렇게 쓰면 그 자리에 1,2,3이 남습니다.(그냥 괄호 벗기기용 연산)
let data1 = [1,2,3];
let data2 = [...data1];
console.log(data1 === data2) //false 나올듯
위의 코드에서는 data1에 있던 자료들을 괄호 벗긴다음 다시 array로 만들어줍니다.
그럼 다른 완전 독립적인 array 복사본을 생성해줄 수 있습니다.
이런 독립적인 사본을 shallow copy 아니면 deep copy라고 합니다.
정리
- 리액트에서 array/object state를 수정하고 싶으면 독립적인 카피본(shallow copy)를 만들어서 수정하는 것이 좋습니다.
- [...기존state] , {...기존state} 이렇게 하면 독립적인 카피가 생성됩니다.
참고자료
https://codingapple.com/course/react-basic/
'프론트엔드 > react' 카테고리의 다른 글
React - 모달창 만들기 (0) | 2023.07.27 |
---|---|
React - Component (0) | 2023.07.27 |
React - 버튼에 기능개발을해보자 & 리액트 staet변경하는 법 (0) | 2023.07.26 |
React - state (0) | 2023.07.26 |
React - 리액트에서 레이아웃 만들 때 쓰는 JSX문법 3개 (0) | 2023.07.26 |