ygreenb
yellowgreenblue
ygreenb
전체 방문자
오늘
어제
  • TIL (130)
    • Algorithm & Data Structure (70)
      • 이론 (4)
      • 프로그래머스 (54)
      • 백준 (12)
    • JAVA (4)
    • Android Studio (9)
    • Database (1)
    • WEB (25)
      • HTML+CSS (7)
      • Javascript (5)
      • React (11)
      • Django (1)
      • Node.js (1)
    • Computer Vision (13)
    • Git (8)

블로그 메뉴

  • HOME
  • TAG
  • GITHUB

공지사항

인기 글

태그

  • getOrDefault
  • 해시
  • Queue
  • 백준
  • dfs
  • git bash
  • sort
  • kotiln
  • 안드로이드
  • greedy
  • PriorityQueue
  • java
  • 깃
  • BFS
  • 깃허브
  • 코틀린
  • Comparator
  • git
  • stack
  • HashMap
  • reactjs
  • React
  • 프로그래머스
  • entrySet
  • Android
  • 프로그래머스 Lv.2
  • compareTo()
  • Arrays.sort()
  • DP
  • 스택/큐

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ygreenb

yellowgreenblue

WEB/React

[React] State

2022. 1. 28. 09:19

Intro

  • 버튼을 몇 번 클릭했는지 세는 어플
  • React.js의 state
    • 컴포넌트에 state 추가
    • state 변경 시 UI 리렌더링

state란?

기본으로 데이터가 저장되는 곳.
이 어플에서는 버튼을 몇 번 클릭했는지 세는 counter. 즉 바뀌는 데이터를 state로 만들 수 있다.

 

컴포넌트나 JSX에 변수(데이터)를 추가하고 싶을 때

바닐라 JS  => ${변수}로 전달
 span.innerText = `Total clicks: ${counter}`;
React JS => 단순히 중괄호에 변수를 넣어준다.
<h3>Total clicks: {counter}</h3>

 

데이터가 변경되어, 사용자에게 변화된 내용을 보여주고 싶을 때 (리렌더링)

1. render 함수를 다시 호출해 UI 업데이트


데이터가 변경될 시, render 함수를 호출해 화면을 새롭게 업데이트 하는 방법
이다.
이 어플에서 render 함수가 호출되는 2가지 상황과 counter의 변화를 비교하면 다음과 같다.

  1. 어플리케이션이 처음 실행될 때 -> render 함수 호출
    -> 최초 실행 시 Container 컴포넌트를 root div에 담아준다.
    -> Container함수 호출돼서 React element 반환
    -> counter 0
  2. 버튼의 클릭 시 등록한 이벤트 리스너인 countUp() 호출
    -> counter 증가 -> render 함수 호출 ( 사용자에게 바뀐 데이터를 보여주기 위해서 리렌더링함)
    -> 최초 실행 시 Container 컴포넌트를 root div에 담아준다.
    -> Container함수 호출돼서 React element 반환(이때, Container 컴포넌트가 바뀐 counter값을 가지고 업데이트)
    -> counter 1 (업데이트된 값)

 여기서 눈여겨볼 점은 버튼 클릭 시 Container 컴포넌트 전체를 리렌더링하는거지만 실제론 HTML 태그 안에서는 변화되는 숫자(counter)만 바뀌고 있다는 것이다. ( 새 컴포넌트를 생성하거나, 전체를 다시 만들지 않고 )

<script type="text/babel">
    const root = document.getElementById("root");
    let counter = 0;
    function countUp(){
        counter = counter + 1;
        render();
    }
    function render(){
        ReactDOM.render(<Container />, root); 
    }
    const Container = () => (
        <div>
            <h3>Total clicks: {counter}</h3>
            <button onClick={countUp}>Click me</button> 
        </div>
    );
    render();
</script>

하지만 위 방식은 데이터가 바뀔 때마다 render 함수를 반복적으로 호출해줘야 한다는 단점이 있다. 

2. useState 함수를 이용해 리렌더링


userState함수는 React.js 어플 내에서 데이터를 보관하고 자동으로 리렌더링을 일으킬 수 있는 방법이다.

useState 함수는 배열 하나를 주는데, 배열의 첫 번째 요소는 우리가 담으려는 data값이고, 두 번째 요소는 이 data값을 바꿀 때 사용하는 modifier이다. 우리는 배열의 데이터를 [0], [1] 같은 형식으로 값을 가져오지 않고 데이터에 counter나 modifier 같은 이름을 붙여 사용하도록 한다.

const data = React.userState(); // [undefined, f]
const [counter, modifier] = React.useState(0); // 초기값 0 할당 [0, f]
// 즉 위의 코드 한줄이 아래 4~7 코드를 대신하고있다는 걸 알 수있음.
let counter = 0;
function countUp(){
 //code
 }


아무튼, React.useState 함수는 counter 같은 데이터를 숫자형 데이터로 건네주고, 그 데이터 값을 바꿀 함수(modifier, 밑에서는 setCounter)도 함께 준다.
modifier 함수를 가지고 state를 변경할 때 컴포넌트가 재생성된다. 즉, 데이터(state)가 바뀔 때마다 컴포넌트를 리렌더링하고 UI를 refresh한다. 물론, 전체 화면이 리렌더링이 되는것이 아니고 오직 modified 컴포넌트(counter)만 리렌더링된다.

state를 세팅해주는 2가지 방법 (setState)

  1. setCounter(5) => 직접 값을 설정하는 것
  2. 현재 state를 바탕으로 다음 state를 계산하는 방법
    1. setCounter(counter+1) => 직접 값을 설정해주기
    2. setCounter((current) => current + 1) ; => 함수 전달하기 ( 더 안전한 방법 )
      (첫번째 인자 : 현재값, 함수의 return 값 : 새로운 state)

state를 세팅하기 위해서 setCounter() 함수를 사용했다. setCounter() 함수에는 직접 값을 설정하거나 함수를 전달해 줄 수 있는데, 함수는 언제나 현재 state를 얻도록 해준다. 따라서 예상치 못한 업데이트가 다른곳에서 일어났다고 해도, 그게 혼동을 주는걸 방지하기 때문에 더 안전하다.

<script type="text/babel">
    const root = document.getElementById("root");
    function App() {
        const [counter, setCounter] = React.useState(0);
        const onClick = () => {
            //setCounter(counter + 1);
            setCounter((current) => current + 1);
        }
        return (
            <div>
                <h3>Total clicks: {counter}</h3>
                <button onClick={onClick}>Click me</button>
            </div>
        );
    }
    ReactDOM.render(<App />, root);
</script>

※추가 참고. jsx에서는 속성으로 class나 for을 사용할 수 없다. 그 대신 className과 htmlFor이라고 쓴다.

 

저작자표시

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

[React] API 사용하기  (0) 2022.02.02
[React] 배열 State  (0) 2022.02.02
[React] Effects (useEffect, clean-up)  (0) 2022.01.29
[React] Props (Memo, Props Types)  (0) 2022.01.28
[React] Component, JSX  (0) 2022.01.26
    'WEB/React' 카테고리의 다른 글
    • [React] 배열 State
    • [React] Effects (useEffect, clean-up)
    • [React] Props (Memo, Props Types)
    • [React] Component, JSX
    ygreenb
    ygreenb
    개발공부기록장

    티스토리툴바