본문 바로가기
React/React Basic

[React] class comp 2 | setState

by CodeMia 2022. 4. 22.

버튼 누르면 이름 바뀌게 하기 

하드 코드 되어있는 다음과 같은 화면이 있다. 

Change Name 버튼을 눌렀을 때

이름이 Lia로 바뀌도록 해보자. 

 

 

 

안에 있는 내용을 다이나믹하게 바꿔보자. 

 

 

이런 경우 이름이 바뀌어야 하므로 state로 바꿔준다. 

 

 

State

local state 또는 state라고 한다. 

변수와 마찬가지고 정보를 담고 있지만

변수는 랜더가 될 때마다 변하지 않지만

state는 수시로 바뀐 정보를 담을 수 있다. 

 

 

그러면 state를 만들려면 어떻게 해야할까? 

constructor() 함수가 필요하다 

 

 

constructor( )

이 메소드는 App 컴포넌트가 읽혀질 때

constructor() 함수 안에 든 내용이 맨 먼저 읽혀진다. 

 

 

super( ) 

constructor() 함수를 부르기 위해 필요하다. 

constructor() 함수 쓰면 자동으로 같이 써준다. 

this 를 사용할 수 있게 한다. 

subclasses를 사용할 수 있게 된다.

super(props)을 부를 수 있게 한다. 

 

 

 

 

 

 

 

this: this App class의 referencing을 한다. 

this.state: 이 App class에 state를 만든다. 

json 오브젝트의 형태로 원하는 벨류를 담아준다. 

key:value 형태로 적어준다. 

 

 

 

{ }를 사용하여 자바스크립트 변수로 바꿔준다. 

이제는 변수가 다이나믹하게 변하게 되었다. 

이 변수가 바뀔 때마다 리액트는 리렌더를 할 것이다. 

 

 

버튼을 눌렀을 이름이 바뀌게 해보자. 

onClick property를 이용하고 콜백함수를 넣어 실행 한다. 

 

 

 

여기서 this.state.name='Lia'로 바로 지정해 주면 될 거라고 생각할 수 있다.

하지만 콘솔에서는 내용이 바뀌어도 화면에서는 이름이 바뀌지 않는다. 

 

 

 

콘솔에서는 이름이 바뀌었지만

 

 

 

버튼을 아무리 눌러도

그대로 Jane으로 되어있고 이름이  바뀌지는 않는 것을 볼 수 있다.

 

 

 

이 때 re-render가 필요하다 

re-render는 DOM을 업데이트해서 UI를 리페인트 하는 작업이다. 

 

 

 

자동 re-render가 되지 않는 이유

name이 Jane에서 Lia으로 바뀌었으니

오브젝트가 바뀌었다고 생각하지만 오브젝트가 바꾸는 것이 아니다

가리키고 있는 화살표가 바뀐 것이다. 

 

 


자바스크립트 메모리 

자바스크립트 memory를 살펴보자 

 

 

obj1 변수명이 벨류 {name: 'Jane'}을 가리키고 있다.

 const obj1 = {name: 'Jane'} 

 

 

cosnt obj2 = obj1 

obj1이 {name:'Jane'}를 포인팅하고 있기 때문에 

obj2도 {name:'Jane'}에 포인팅을 한다. 

 

 

obj2 === obj1 

true 로 나온다. 

obj2 와 obj1은 같은 곳을 가리키고 있다. 

 

 

obj1의 이름을 바꾸면 obj2 내용도 같이 바뀌어져 있다. 

obj1.name = 'Lia' 

 

obj1 

 {name: 'Jane'} 

 

obj2 

 {name: 'Jane'} 

 

두 메모리로 따로 저장한 것이 아니라

둘 다 같은 메모리를 가리키고 있다

 

 

 

 

다른 경우를 보자 

 

새롭게 obj3이라는 변수에 obj1을 저장 한다. 

const obj3 = Object.assign({}, obj1)

 {name: 'James'} 

겉으로 보기에는 같은 내용이 나온다. 

 

하지만 

obj1 === obj3 

false 

두 오브젝트는 다른 오브젝트이다.

 

 

또 다른 경우 똑같이 타이핑해서 저장하는 경우도 새로운 메모리를 차지 하는 것이다. 

const obj4 = {name: 'James'} 

 

obj1 === obj4 

false 

 

obj3 === obj4 

false 

 


 

위의 상황처럼 state에 다른 메모리로 바뀌어 있으면

리액트가 알아채고 setState() 함수를 이용해서 

자동 리렌더를 해야한다.

 

 

this.setState를 적어주고

오브젝트 안에 키와 벨류를 입력해 준다. 

this.setState({name: 'Lia'})

 

 

 

setState를 써줄 때 shallow merge 사용

name 키에 스트링이 바로 오는 것이 아니라

firstName과 lastName으로 나뉘어져 있는 경우를 살펴보자.

 

 

 

 

 

setState에서 name 키에 firstName, lastName을 따로 넣지 않고 

그냥 string을 적어버린 경우 

이 땐 버튼을 눌렀을 때 화면에 나오는 게 없다. 

 

 

이름이 사라졌다. 

 

 

name 키를 맞춰주고, name 안에 firstName과 lastName까지 각각 넣어줘야 한다. 

오브젝트면 오브젝트로 맞춰줘야 한다. 

 

 

 

 

다음 포스트에서는 setState로 함수 통과시키는 것을 배워보자. 

 

 

댓글