본문 바로가기
React/React

[React] state

by Rayched 2024. 1. 29.

1. 개요 / 버튼 예제 구현

React를 활용해서 버튼 하나와 버튼을 클릭한 횟수를 보여주는 간단한 예제를 하나 만들어보자.

//<script type="text/babel">
let Counter = 0;

function ClickCount(){
	Counter = Counter + 1; 
}

const App = () => {
      return (
        <div>
            <h4>아래 버튼을 클릭해보세요. 👇</h4>
            <button onClick={ClickCount}>버튼</button>
            <h4>버튼 클릭 횟수 : {Counter}회</h4>
        </div>
    );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);

//</script>

'버튼'을 클릭해도, 하단의 버튼 클릭 횟수에는 변화가 없다.

 

'index.html'의 'root' 요소에 App Component가 성공적으로 Rendering 됐다면

아래 이미지처럼 안내 메시지와 버튼 그리고 버튼 클릭 횟수를 기록하는 문구가 보일 것이다.

여기서 버튼을 클릭했을 때 하단의 '버튼 클릭 횟수: 0회'에 변화가 있어야 하지만

실제로 확인해 보면 처음 상태 그대로인 것을 볼 수 있다.

 

버튼을 클릭했을 때, ClickCount 함수가 정상적으로 실행되는지 확인하기 위해서

해당 함수 내부에 아래 코드를 추가한 다음 Console 탭을 확인해 보자.

//function ClickCount(){
    /* Counter = Counter + 1; */
    console.log("Button Click");
//}

 

버튼을 클릭하면, ClickCount 함수 호출, 위의 메시지를 Console 창에 출력한다.

 

Console 창에 출력되는 메시지를 통해서 버튼을 클릭했을 때, ClickCount 함수가 호출되고

버튼 클릭 횟수를 기록하는 변수 Counter의 값에도 변화가 생긴다.

변수 Counter의 값이 변해도, 이를 참조하는 '버튼 클릭 횟수' 요소에는 반영이 되지 않을까?

 

이는 App 함수가 처음 Rendering 될 때만 실행되고 이후에 예제에서 버튼을 클릭

click eventListener인 ClickCount 함수가 실행, 해당 함수에서 변수 Counter의 값을 변경한다고 해서

버튼 예제 Component를 return 하는 App 함수의 재실행과는 이어지지 않기 때문이다.

 

따라서 위와 같은 문제는 버튼 요소의 EventListener인 ClickCount 함수 내부에 App 함수를

index.html 파일의 root 요소로 rendering해주는 코드를 추가하는 것으로 해결할 수 있다.

//function ClickCount(){
	/* 
    	기존 코드
        Counter = Counter + 1;
     */
	root.render(<App />); //new
//}

버튼을 클릭하면, Console 창에 임의의 메시지를 출력, 버튼 클릭 횟수가 업데이트된다.


위의 예제를 구현하는 과정에서 '버튼'의 Click Event Listener인 ClickCount 함수가 실행

해당 함수에 의해 변수 Counter의 값이 업데이트돼도, App Component를 Re-rendering 하지 않으면

이를 참조하는 '버튼 클릭 횟수' 요소에는 변화가 생기지 않는다는 것을 알았다.

 

지금까지 구현했던 코드는 '버튼'을 클릭했을 때, 버튼 클릭 횟수를 기록해 두는 변수 Counter의 값이 바뀌고

이를 웹 페이지에 반영하기 위해서 일일이 수동으로 App Component를 다시 Rendering을 해줘야 했다.

 

물론 이런 식으로 구현하는 것도 하나의 방법이긴 하지만, 좀 더 편한 방식이 있다.

'state'를 활용하면 외부에서 App Component를 다시 Rendering을 할 필요 없이

App Component가 자체적으로 Re-rendering이 가능하게 할 수 있다.


2. state의 정의

① state

ReactJS에서 'state'는 변수처럼 React에서 데이터를 보관하는 방법 중 하나

Component 내부에서 변경할 수 있는 데이터를 보관하기 위해 사용하는 JavaScript 객체이다.

 

let, const로 선언한 변수의 값이 변경되어도 Re-rendering이 발생하지 않지만

'state'는 보관하고 있는 값이 바뀌면 해당 state를 참조하는 Component에 Re-rendering이 발생한다.

 

'state'의 값은 'setState()'라는 함수를 통해서 수정할 수 있다.

 

'setState()' 함수는 state를 변경할 때 사용하는 함수이다.

'state'에 변경 사항이 발생하면 해당 state를 참조하는 Component를 다시 랜더링 한다.

(하위 Component도 Re-rendering 된다.)


② state 사용해 보기

 

제일 먼저 'useState()' 함수를 선언해 주자.

//<script> 태그 통해서 React, ReactDOM을 Import한 상태

const Test = React.useState();

 

더보기

React App의 초기 설정을 'create react app' 방법으로 하였을 경우에는

먼저 useState를 Import를 해주고 그다음에 useState()를 선언해야 한다.

import { useState } from 'react';

const Test = useState();

'useState()' 함수는 state와 이를 수정하는 setState() 함수가 담긴 배열을 return 한다.

useState() 함수의 return 값을 Test라는 변수에 담았으니 console 창에서 이를 확인해 보자.

state의 초기 값을 설정하지 않았기 때문에 undefined가 할당됐다.

'useState()' 함수를 통해 state와 setState()를 생성할 때 임의의 값을 인자로 전달하면

해당 값을 state의 초기 값으로 지정하는 것이 가능하다.

 

const Test = React.useState("Test");
console.log(Test);

 

useState의 인자로 전달한 문자열이 state의 초기 값으로 할당됐다.

 


 

'useState()'를 통해서 state와 이를 수정하는 함수인 setState()를 생성하고

useState()에 인자 값을 전달, 해당 값을 state의 초기 값으로 할당하는 방법을 알았으니

 

이제 useState()의 return 값인 '[state, setState()]' 배열을

구조 분해 할당 문법을 활용해서 임의의 변수 Test, setTest로 각각 할당해 보자.

const [Test, setTest] = React.useState("state Exam");
console.log(Test, setTest);

 

 


3. 버튼 예제 Update

'useState()' 함수를 통해서 state와 이를 수정할 수 있는 setState() 함수를 생성하고

구조 분해 할당 문법을 통해 임의의 변수에 할당하는 방법까지 알았으니 이걸 버튼 예제에 적용해 보자. 

//<script type="text/babel">

//Delete Start
let Counter = 0;
function ClickCount(){
    Counter = Counter + 1;
    root.render(<App />);
    console.log("Rendering");
}
//Delete End

const App = () => {
    return (
        <div>
            <h4>아래 버튼을 클릭해보세요.</h4>
            <button onClick={ClickCount}>버튼</button>
            <h4>버튼 클릭 횟수 : {Counter}회</h4>
        </div>
    );
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
//</script>

 

'Delete'로 표시한 코드를 전부 지우고, App 함수 내부에 useState() 함수를 선언하고

해당 함수 (useState)의 return 값을 변수 Counter, setCounter에 각각 할당하도록 하자.

 

const App = () => {
    const [Counter, setCounter] = React.useState(0); //new
    
    /*기존 Source Code*/
}

그다음 버튼을 클릭했을 때, 하단의 '버튼 클릭 횟수'에도 변화가 있어야 한다.

이를 위해서 <button> 요소의 Event Listener인 ClickCount 함수를 App 함수 내부에 선언해 주자.

 

여기서 버튼 클릭 횟수를 기록하는 변수 Counter는 state의 값을 참조하기 때문에

ClickCount 함수 내부에서 state를 수정하는 setCounter 함수를 호출하고

setCounter 함수의 인자로 'Counter + 1'을 전달해 주자. (Counter의 현재 값에 1을 더함)

 

그러면 해당 함수를 통해서 state의 값이 0에서 'Counter + 1'로 변경되며

state를 참조하는 변수 Counter의 값 또한 동일한 값인 'Counter + 1'로 변경된다.

 

const App = () => {
    const [Counter, setCounter] = React.useState(0);
    
    function ClickCount(){
    	setCounter(Counter + 1);
        console.log("Rendering");
    }
    
    /* 기존 Source Code */
}

 

 


4. 마치며

오늘 'ReactJS'의 'state'에 대한 아주 기본적인 내용의 정리가 끝났다.

사실 공부한 기록을 좀 더 효율적으로 남기기 위해서 하루동안 공부한 것과 그 과정에서 느낀 것을 정리하는

'TIL, Today I Learned'을 시작했는데 나란 인간이 워낙 게을러서 그런지 모르겠지만

처음 생각과는 다르게 하루 만에 끝내지 못하고 3일 정도는 걸린 것 같다.

 

좀 더 공부를 꾸준히 하고 싶지만, 생각보단 쉽지가 않다.

알바를 안 하는 날에는 여유 시간이 많이 생겨서 공부하기 수월할 것 같았지만

막상 생각해 보니 공부를 한 날보다 그냥 아무것도 안 하고 빈둥빈둥거린 시간이 더 많은 것 같다.

 

이러면 안 된다는 것을 알고 있지만, 그걸 행동으로 옮기기는 쉽지 않은 것 같다...😞

 

좀 더 분발하자.


📔 Reference
처음 만난 React / Inflearn
React 영화 웹 사이트 만들기 / Nomad Coders
State and LifeCycle / React 공식 문서

[리액트] state를 사용하는 이유 / Velog '비얌'

💻 Update Log
- 2024.01.29 'state' 정의 및 예제 작성 완료
- 2024.02.04 본문, 목차 링크 추가, 목차에서 'setState()' 항목 삭제

 

 

'React > React' 카테고리의 다른 글

[React] Toggle Button 구현하기  (0) 2024.08.07
[React Query] useQuery()  (0) 2024.08.03
[React] Plugin "react" was conflicted between "package.json  (0) 2024.06.03
[React] React Component 생성법  (0) 2024.01.05
[React] 개발 환경 설정  (0) 2023.12.12