글 수정버튼을 누르면, 내용이 바뀌게 만들고 싶어요.
글제목 중 '남자코트추천' => '여자코트추천'으로요
function App(){
let [글제목, 글제목변경] = useState( ['남자코트 추천', '강남 우동맛집', '파이썬 독학'] );
return (
<button onClick={ ()=>{ ??? } }> 수정버튼 </button>
)
}
그래서 이렇게 바꿨습니다
function App(){
let [글제목, 글제목변경] = useState( ['남자코트 추천', '강남 우동맛집', '파이썬 독학'] );
return (
<button onClick={ ()=>{글제목변경(['남자코트 추천', '강남 우동맛집', '파이썬 독학'])} }> 수정버튼 </button>
)
}
state 변경함수는 ()안에 넣은 걸로 기존 state를 갈아치워주니까 저렇게 집어넣으면 됩니다.
그러면 여기서 문제, 왜 그냥 글제목변경('여자코트추천')은 안될까요?
기존 state를 갈아치워준다니까요?!?!?!
(코딩은 자의적으로 하는게 아니라구염...! 저도 맨 처음에 무논리로 이렇게 쳤어요 ㅠㅋ)
하지만, 지금 코드는 확장성이 부족합니다.
만약 useState의 () 안의 내용이 3개가 아니라 100개면 어떡하죠?
항상 새로 state를 쓰지말고, 기존 state를 첫글만 사알짝 바꿔서 state 변경함수에 집어넣는 식으로 개발해봅시다아
function App(){
let[글제목, 글제목변경] = useState(['남자코드추천','강남우동맛집','파이썬독학']);
return(
<button onClick = { ()=>{
let copy = 글제목;
copy[0] = '여자코트 추천';
글제목변경(copy)
}}>수정버튼</button>
)
}
array, object 같은 자료 다룰때는 원본 데이터를 직접 조작하는 것보다는
기존값은 보존해주는 식으로 코드를 짜는게 좋은 습관이다. (갑자기 원본자료 필요할 수도 있으니)
그래서 let copy 같은 변수에다가 기존 array 를 복사해놓고 그걸 조작하는 식으로 코드를 짜면 조금 더 안전하다.
그런데 지금 수정버튼 눌러도 안바뀌눈데여?
function App(){
let[글제목, 글제목변경] = useState(['남자코드추천','강남우동맛집','파이썬독학']);
return(
<button onClick = { ()=>{
let copy = [...글제목];
copy[0] = '여자코트 추천';
글제목변경(copy)
}}>수정버튼</button>
)
}
요렇게 살짝만 바꿔줘야 동작합니다
[...글제목] 라고 표기하면, 기존[]을 벗겨주고 새로 []를 씌워주는 것을 뜻합니다.
아예 새로운 배열을 뱉어내는 거죠..
먼소린지 모르겟다구요? 그럼 state 변경함수의 동작원리에 대해 자세히 알아보죠 ㅎ
state 변경함수의 동작원리
state 변경함수를 쓸때
먼저 기존state === 신규state 이렇게 검사해봅니다. 그런데 여기서 둘이 같으면 state를 변경해주지 않습니다.
그래서 위에 있는 코드에서도 글제목변경(copy)를 해도 copy라는 변수가 기존state와 같으니까 변경을 안해준겁니다.
Q. 분명 copy 안 내용이랑 기존 state 안 내용이랑 자료가 다른데 왜 같다고 함??????
제가 이렇게 콘솔을 찍어봤는데도 같다고 나오네요...
array/object 동작원리
자바스크립트에서 let arr = [1,2,3] 이렇게 만들면
[1,2,3] 자료는 램이라는 가상공간에 몰래 저장이 되고,let arr 변수엔 그 자료가 어디있는지를 가리키는 화살표만 남습니다
그래서 array/object 를 복사하면, 이런식으로 하게 되는데,
let data1 = [1,2,3];
let data2 = data1 // data2에 data1의 주소공유
여기서 data1과 data2는 각각 [1,2,3]을 별개로 저장하는게 아니라, 같은 주소를 공유합니다.
그래서, data1을 변경하면 data2도 변경되게 됩니다
반대로 data2를 변경하면 data1도 변경되게 됩니다
let data1 = [1,2,3];
let data2 = data1; //복사
data2[0] = 1000; //data2 내부 변경
console.log(data2 === data1) //true 나올듯
(참조자료형이라 그래요 ㅎ,,, 원시자료형과 참조자료형의 차이를 아시는 분은 이해가 빠를듯)
그래서 아까처럼
let copy = 글제목; // 여기서 글제목은 [] 배열입니다
copy[0] = '여자코트추천';
글제목변경(copy)
이렇게 치면, 컴퓨터는 기존 state와 새state가 같다고 생각하고 굳이 변경을 안해줍니다 (화살표가 가리키는 주소가 같으니까)
하지만
let copy = [...글제목] // 새로운 배열탄생!
copy[0] ='여자코트추천';
글제목변경(copy)
[...글제목] 이라고 써주면 기존 []를 벗고, 새로운 []를 씌워주기 때문에
새로운 배열의 state, 기존state와 다르다고 인식하고
변경을 해줍니다
[...] 이게 뭔가요?
spread operator 라고 하는 문법인데, array나 object 자료형 왼쪽에 붙일 수 있으며
그냥 괄호를 벗겨주세요~ 라는 뜻입니다
array,object 복사할때 새로운 array,object(독립적인 복사본) 를 만들때 많이 사용합니다
한줄요약 : array,object는 그냥 다른변수에 할당해주면 안되고, [...]를 사용해서 독립적인 복사본을 만들어주는게 좋다!
'React' 카테고리의 다른 글
리액트에서 동적인 UI 만드는 방법 (0) | 2023.03.25 |
---|---|
컴포넌트 : 많은 div를 한단어로 줄이고 싶다면 (0) | 2023.03.24 |
리액트 state 변경하는 법 (0) | 2023.03.24 |
자꾸 바뀌는 데이터는 State에 담아요! (변수 ㄴㄴ) (0) | 2023.03.24 |
리액트 기본 문법 3개 (0) | 2023.03.24 |