React State에 대해서

최재홍·2022년 7월 8일
1

리액트에 컴포넌트가 있는데 컴포넌트에 입력되는 것은 "Prop"이다. 그리고 Prop에 의해 반환되는 return 값이 새로운 UI가 된다.

Prop과 함께 컴포넌트 함수를 다시 실행해서 새로운 return값을 반환하는 데이터가 있는데 이것이 "State"이다.

PropState 모두 컴포넌트를 새로이 작동시켜 새로운 UI를 얻게 한다.

Prop은 컴포넌트를 사용하는 외부자를 위한 데이터이고,
State는 컴포넌트를 만드는 내부자를 위한 데이터이다.

function App() {
  const mode = "WELCOME";
  const topics = [
	{id:1, title:'html', body:'html is...'},
	{id:2, title:'css', body:'css is...'},
	{id:3, title:'js', body:'js is...'}
]
let content = null;
if(mode === "WELCOME") {
  content = <Article title="Welcome" body="Hello, WEB></Article>
} else if(mode === "READ") {
  content = <Article title="Read" body="Hello, Read"></Article>
}

	return (
	  <div>
		<Header title="REACT" onChangeMode={function(){
        alert('Header');
        }}></Header>
		<Nav topics={topics}></Nav>
		{content}
      </div>
	);
}

이와 같이 <App>컴포넌트의 최상단에 "mode"라는 변수를 지정하고
"content"라는 변수에 대해서 기본적으로 null값을 부여했다가,
mode변수의 값이 "WELCOME"과 "READ" 사이에서 변화함에 따라서 <Nav>컴포넌트 아래에 서로 다른 두개의 <Article>컴포넌트가 랜더링 되도록 애플리케이션의 로직을 구현했다고 해보자.

이제 남은 것은 이벤트가 발생함에 따라서 "mode"의 변수값을 변경시키는 것이다.

<div>
  <Header title="WEB" onChangeMode={() => {
    mode = "WELCOME";
  }}></Header>
  <Nav topics={topics} onChangeMode={(id)=>{
   mode = "READ";
  }}></Nav>
  {content}
</div>

이렇게 코딩하여 <Nav>컴포넌트에서 id라는 인자를 받아 "mode"의 값이 "WELCOME"와 "READ" 사이에서 변하도록 조작을 하고 값을 변화시켜보지만 함수는 작동하지 않는다.

<App>이라고 하는 최상위 컴포넌트를 재실행 시키지 못 했기 때문이다.

이럴 때 사용하는 것이 State라는 개념이다.
State라는 장치를 사용하기 위해서는 "useState"라는 훅을 사용해야 한다.

훅은 리액트에서 기본적으로 제공하는 함수고, 이를 사용하기 위해서는 js파일 최상단에서 import해왔음을 밝혀야 한다.
import {useState} from 'react';

이제 지역변수로 선언된 "mode"를 state로 업그레이드 해보자.

const mode = "WELCOME"
//위에서 아래로 변환
const _mode = useState("WELCOME")

여기서 "_mode"라는 변수에 대해서 console.log()를 출력해보면

['WELCOME', f]
0: 'WELCOME'
1: f()

useState라는 함수는 배열을 리턴하고, 그 배열의 0번째 요소는 '상태의 값' 을 읽을 때 쓰는 데이터, 1번째 데이터는 그 상태의 값을 변경할 때 사용하는 '함수'

정리하면 다음과 같다.

const _mode = useState('WELCOME');
const mode = _mode[0];
const setMode = _mode[1];
//따라서
const [mode, setMode] = useState('WELCOME');

위의 세 줄을 가장 아래의 한 줄로 줄여서 표현할 수 있다. 마지막 줄이 useState의 통상적인 표현법이기 때문에 익숙해지도록 하자.

그렇다면 아까 props를 통해 "mode"의 변수값을 바꾸려고 했다가 실패한 컴포넌트를 다시 한번 보자.

<div>
  <Header title="WEB" onChangeMode={() => {
    setMode("WELCOME");
  }}></Header>
  <Nav topics={topics} onChangeMode={(id)=>{
    setMode("READ");
  }}></Nav>
  {content}
</div>

"mode"의 값이 "setMode"를 인해 바뀌면서 <App>컴포넌트가 재시동되게 된다. 그리고 "useState"가 "mode"값을 "READ"로 세팅하면서 그에 따라 리턴되는 값이 변하고 화면에 출력되는 UI가 변하게 된다.

이때, "useState"라는 함수에 의해서 정의된 배열 [mode, setMode]는 그 자체로 배열 속 원소일 뿐 고정적인 명칭이 아니기 때문에 꼭 "mode"나 "setMode"로 명시될 필요는 없다.

0개의 댓글