2023. 4. 15. 12:15ㆍ개발/React
state란
리액트에서 데이터를 다루는 대표적인 방법으로 props와 state가 있다. props는 부모 컴포넌트에서만 수정 가능하며 자식 컴포넌트는 읽기만 가능한 단방향 데이터 메커니즘이다. 반면 state는 컴포넌트 내부에서 변경 가능한데이터이다.
단어 그대로 상태값을 의미하는데 기존의 자바스크립트나 개발언어에서도 필요하다면 다양한 상태값을 선언하고 사용하였다. 하지만 리액트에서는 상태라는 개념은 가상돔 개념과 연결되면서 상태의 변경이 발생할 경우 UI를 리 랜더링 하게 되는 기준값이 되었다.
즉, state는 컴포넌트 내부에서 변경 가능한 값이며, 변경이 일어날 경우 화면이 리랜더링 되도록 하는 기준값이라는 것.
함수형 컴포넌트에서 state 사용하기
리액트 이전 버전에서는 클래스형 컴포넌트에서만 state를 사용할수 있었다. 하지만 버전이 업데이트 되면서 함수형 컴포넌트에서도 useState라는 hook을 사용하면 state를 사용할 수 있다.
hook은 일종의 정해진 역할을 하는 함수이다. 여러 hook이 존재하는데 useState는 state의 값 지정해주고, 해당 값을 컨트롤 할수 있는 메서드를 반환한다. 해당 메서드는 일종의 setter라고 볼 수있다.
/** useState();
* @param inintVale 초기값
* @return 초기값을 가지고 있는 변수 생성
* @return 주로 셋으로 시작하는 이름을 지정해줌set~~, 초기값을 컨트롤 할수 있는 메서드
* 이걸 구조분해 할당으로 받으면 된다.
*/
//App.js
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0)
return (
<div>state에 대한 예제입니다</div>
);
}
export default App;
위의 코드를 보자 count라는 state를 생성하고 기본 값으로 0을 부여해 주었다. 또 setCount라는 이름의 메서드를 반환한다. 해당 메서드에 특정 값을 넣으면 state count의 값이 변경되고 화면이 리랜더링 된다.
아래의 코드를 살펴보자. name이라는 state에 산할아버지라는 값을 부여했고 최초 값이 부여되면서 화면은 랜더링 된다. 이후 버튼을 클릭할 경우 setName함수가 실행되면서 ‘산할아버지~ 구름모자 썻네~’로 name 값이 변경 된다. 이로서 name state가 변경되어서 화면은 다시 리랜더링 된다.
import React, { useState } from 'react';
function App() {
const [name, setName] = useState('산할아버지! 모자 없다.')
function btnClickEventHandle (){
setName("산할아버지~ 구름모자 썻네~")
}
return (
<div>
{name}<br/>
<button onClick={btnClickEventHandle}>클릭</button>
</div>
);
}
export default App;
불변성
state의 변경이 발생할 경우 화면이 리랜더링 되기 때문에 state가 중요한 개념이라는 것은 알 수있다. 그렇다면 state의 변경여부는 어떻게 확인 할까? 이는 메모리 상 데이터가 참조하는 주소가 변경되면 state가 변경된 것으로 인식한다. 메모리에 할당되는 영역은 자바스크립트 문법과 관련이 깊다. 자바스크립트 데이터 유형에는 원시타입 데이터와 참조타입 데이터가 있다.
원시타입 데이터는 불변성을 가진다. 불변, 즉 변하지 않으며 메모리의 데이터는 변하지 않지만 새로운 주소가 할당되고 그 주소에 새로운 값이 들어가게 되고 그 주소값을 선언된 변수 혹은 상수와 연결해준다. var a = 1 이라고 선언한 뒤 a = 2를 선언하게 되면 처음에 a는 1이라는 값의 주소를 참조하고 있다가 추후에 2라는 값의 주소값을 가진다.
반면 참조타입 데이터는 불변성이 가지지 않는다. 즉 값이 실질적으로 변화가능하다. 이는 참조타입 데이터는 길이나 크기가 정해져 있지 않고 추가되거나 변경될 수 있기 때문이다. 대표적인 참조타입 데이터인 배열은 값이 추가되고 수정될 가능성이 크기 때문에 참조타입으로 관리하게 된다.
참조타입 데이터는 값이 수정되면 해당 값이 실제로 변경되고 해당 값의 주소를 가지고 있던 변수값의 주소는 변경되지 않는다.
이 개념을 리액트에 그대로 적용하게 되면 원시타입 데이터는 state로 관리할 경우 변경사항이 바로바로 인식되는데 참조타입 데이터는 실제로 그 값이 변경되었다고 해도 주소가 변경되지 않았기 때문에 state가 변경된 것으로 인식되지 않는다. 따라서 실제 그 값으로 새로운 값을 생성해주면 된다.
import React, { useState } from 'react';
function App() {
let [obj, setObj] = useState({
name : 'youngsimi',
age : 15
})
function btnClickEventHandle(){
console.log("변경 전",obj.name)
obj.name = '영시미'
setObj(obj)
console.log("변경 후",obj.name)
}
return (
<div>
{obj.name}
<button onClick={btnClickEventHandle}>변경</button>
</div>
);
}
export default App;
/*실제 데이터가 변경 되어도 주소가 변경되지 않았기 때문에 화면이 리랜더링 되지 않아서 변경 버튼을 클릭한
이후에도 이전 값만 계속해서 보인다. */
function App() {
let [obj, setObj] = useState({
name : 'youngsimi',
age : 15
})
function btnClickEventHandle(){
console.log("변경 전",obj.name)
obj.name = '영심이'
setObj({...obj})
console.log("변경 후",obj.name)
}
return (
<div>
{obj.name}
<button onClick={btnClickEventHandle}>변경</button>
</div>
);
}
export default App;
/*스프레이드 문법을 사용해서 새로운 값을 생성하여 주소값을 변경해주었다. */
'개발 > React' 카테고리의 다른 글
[리액트] Hooks - useState (0) | 2023.04.24 |
---|---|
[리액트] CSS in JS, Styled Components 란 (0) | 2023.04.17 |
[리액트] Props란, Prop Drilling (칸트 도덕철학) (1) | 2023.04.15 |
[리액트] JSX란? JSX문법 소개 (0) | 2023.04.15 |
[리액트] 컴포넌트란? 리액트 컴포넌트 간단 예제 (0) | 2023.04.14 |