리액트 기초 공부해보기 #4 useState
App안에 number를 증가시키는 add라는 함수를 만들어 보았다.
const add = () => {
};
이거는 그냥
function add(){
}
이거라고 보면 된다.
숫자를 표시할 수 있도록 number 변수를 저 안에 넣고 클릭시 더하기가 되는 버튼을 넣었다. 여기서 add()라고 하면 화면을 그리면서 바로 실행을 하게 되어 버리므로 괄호를 지우고 add만 넣어서 온클릭시 함수가 실행되도록 바인딩만 해놓는다.
화면이 로드될땐 add함수가 실행이 안되고
더하기 버튼을 클릭하니 add함수가 실행된 것을 확인할 수 있다. 하지만 number변수는 저 화면에 반영이 되지 않는다. 이유는 number는 상태값이 아니기때문에(렌더링시점은 상태값 변경시에 렌더링이 이루어짐) ui가 변경이 되지 않는다.
따라서 number를 상태값으로 만들기 위해
코드를 이렇게 변경해준다.
이거는 React안에 hooks라는 라이브러리가 있는데 그걸 이용한것
변수는 number로 만들어진다 변수를 변경하려면 setNumber로 변경하는것 useState에 1을 넣은것이므로 number에 1이 들어간거
이제 number값을 변경해야하는데 기존에 add함수에 number++처럼 변경은 불가능하다.
그렇기에 위 사진과 같이 SetNumber(number+1)이렇게 바꿔줘야 하는데 SetNumber()안에 값을 넣음으로써 리액트한테 number값 변경할게라고 요청을 하는 것이다.
이렇게 상태값으로 만들어 변경해야 App에서 return을 할 수 있다.
이제 더하기를 누르니 숫자가 바로바로 변경되는 것이 화면에 보인다.
또 다른 연습을 해보자.
Sub라는 js파일을 만들고 rsc로 자동완성하면 바로 저렇게 코드가 자동완성된다.
다음 app.js안에 sub.js를 넣는데 이렇게 되면 app.js는 부모가 되고 sub가 자식이 된다.
그럼 number를 변경시(상태가 변경되면 전체가 리빌드된다)
return (
<div>
<h1>숫자 : {number}</h1>
<button onClick={add}>더하기</button>
<Sub />
</div>
);
저 return 안에 코드들이 다 그려지는데 저걸 그리다보면 sub도 같이 그려진다. 즉 부모가 리빌드 될때 자식들도 전부 리빌드 되는것이다. 그럼 여기서 sub는 데이터가 있는것도 아니니 다시 그려질 필요가 없다. 그렇기에 어떤 함수를 써서 다시 그릴 필요 없는 자식은 return을 안시킬 수 있다. 이거는 잘게 쪼개서 컴포넌트화를 했기때문에 가능한건데 이래서 리액트에선 컴포넌트 설계하는게 굉장히 중요하다고 한다.
다운로드 한 데이터를 users 안에 넣고 싶을때
setUsers([...users, ...sample]);
이렇게하면 깉은 복사로 userState([])여기 안에 기본값이 있으면 sample로 업데이트하고, 만약 sample에 없는 값이 기본값으로 들어가있으면 추가가 된다. 하지만 다운로드한 파일 그대로 그냥 덮어 씌우고 싶으면
setUsers([...sample]);
이렇게 하면 된다.
이렇게 download 함수 안에 sample을 setUsers로 users안에 장전을 해놓고 map을 통해 뿌릴 준비를 한다.
다운로드 버튼만 있는 상태에서(왜냐면 지금 users안에는 데이터가 아무것도 없으니까)
다운로드 버튼을 누르면?
이렇게 4건의 데이터가 화면에 뿌려진다.
자, 그럼 이렇게 useState 안에 기본 데이터도 sample에 있는 데이터를 가지고 있는데 저렇게 sample에도 데이터를 넣고 다운로드를 누르면 이건 화면이 다시 렌더링이 되는걸까?
우선
이 return이 실행되려면 위에 function App이 실행이 되어야 한다.
정확히 확인을 하기 위해
로그를 넣어보자.
우선 기본 로직은 화면이 로드 되면 저 4개의 데이터를 map을 통해 배열을 돌면서 화면에 뿌릴것이다. 그럼 여기서 다운로드 버튼을 클릭하면 sample이라는 새로운 데이터 영역을 만들고
이렇게 하면 데이터는 같지만 레퍼런스가 다른 sample이 setUsers에 들어간다.
그렇기에 다른 레퍼런스이기에 데이터를 다르게 인식해서 한번 더 실행될거임
이렇게 처음 화면 로드하면 App이 실행이 되고,
다운로드 버튼을 누르면 값의 변화는 당연히 없겠지만 이렇게 App이 또 실행이 된다.
그럼 이제
sample을 바깥으로 빼고 useState에 sample을 넣어 기본적으로 sample을 들고 있으면?
지금 상황은 저 선언한 sample변수와 useState안에 들어가있는 sample이랑은 같은 메모리를 공유하고 있음
그리고 다운로드를 함수 안에 있는 sample까지 이 세개의 sample은 값도 같고 레퍼런스도 같다.
그럼 마찬가지로 페이지를 일단 로드해보면
App이 실행이 되고,
다운로드 버튼을 눌러도 App이 실행이 되지 않는다.
이유는 레퍼런스의 변경이 없음, 결국 useState라는 상태가 변경되려면 레퍼런스가 변경이 되어야 한다. 그렇기에 깊은 복사를 해야한다는 것
이렇게 [...sample]로 깊은 복사를 하여
페이지 로드 하면서 App이 실행되고, 다운로드를 누르면 App이 또 실행되는 것을 볼 수 있다. 왜? -> 레퍼런스가 변경이 되었으니까
다음은 이렇게 다운로드 클릭시 sample에 푸쉬하여 데이터를 추가하려고 한다.
화면을 로드하고 다운로드 버튼을 클릭하니 sample에는 5번 조자룡의 데이터가 들어가 있다.
이렇게 push로 sample에 데이터를 넣었고 그 상태에서
이렇게 setUsers에 sample을 넣으면 다운로드 클릭시 화면에 5번 조자룡의 데이터가 뿌려 질까?
정답은 No.. 다운로드를 클릭했지만 조자룡의 데이터는 화면에 뿌려지지 않는다.
그렇기에 데이터를 추가 하려면 전에 배웠던 concat을 사용 해야한다.
이렇게 하면 sample의 레퍼런스가 바뀌었으므로 동작이 된다.
잘 동작이 된다. 이 sample은 불변 데이터이기때문에 계속 클릭해도 기존과 같은 데이터이니 a가 한번 추가 되고 더 이상 추가되지 않는다.
concat을 안쓸거면 이렇게 넣을 수도 있다.
다음 다운로드를 계속 클릭시 데이터를 바꿔 조자룡을 계속 추가 해 보려고 하는데
이 ...sample의 값은 불변이기에(항상 4건이기에) 숫자만 계속 바뀌는 것을 볼 수 있다.
신기한 리액트... 이 게시물은 여기서 끝
이 글은 유튜브 메타코딩 채널의 영상을 보며 공부한 내용을 기록한 게시글입니다.
Author And Source
이 문제에 관하여(리액트 기초 공부해보기 #4 useState), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@khs50851/리액트-기초-공부해보기-4-useState저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)