프론트앤드/React

[포스코x코딩온] 웹개발자 입문 과정 8주차 | state 와 useState

영최 2023. 4. 23. 17:54
728x90

1.state란?

 state란 컴포넌트 내부에서 바뀔 수 있는 값을 의미한다.

 React에서 앱의 유동적인 데이터를 다루기 위한 개체로, 계속해서 변하는 특정 상태이다.

 상태에 따라 다른 동작을 할 수 있게 한다.

 

 사용하는 이유는 동적인 데이터이므로, 변수와 달리

 state가 변경될 시 자동적으로 재랜더링해야하기 때문이다.

 

 state와 props의 다른 점은 아래와 같다.

state vs props

 즉, state는 해당 컴포넌트 내부에서 사용되는 값이고,

 props는 부모 컴포넌트에서 상속받아서 자식컴포넌트에서 사용되는 값이다.

 

 앞선 포스팅에서도 말했듯이

2023.04.23 - [프론트앤드/React] - [포스코x코딩온] 웹개발자 입문 과정 8주차 | 컴포넌트(함수형|클래스형)

 

[포스코x코딩온] 웹개발자 입문 과정 8주차 | 컴포넌트(함수형|클래스형)

1. 컴포넌트란? 리액트에서 앱을 이루는 최소 단위를 컴포넌트라고 한다. 리액트에서 화면의 UI요소를 구분할 때 사용하는 단위로, 하나의 가장 작은 조각으로 이해하면 된다. 앞선 블로그 설명

jayoung977.tistory.com

 

 원래 클래스형 컴포넌트에서만 state가능을 사용할 수 있었는데,

 React 16.8버전 이후부터 함수형 클래스에 useState라는 함수를 통해

 state를 사용가능하게 되었다. (함수형 컴포넌트가 무적이 되었다..)

 

 

 그래서 먼저 함수형 컴포넌트에서 어떻게 state가 사용되는지 알아보고 

 이후 클래스형 컴포넌트에서 state 사용하는 법을 비교해서 알아보겠다.

 

 

 가.함수형 컴포넌트의 useState

import { useState } from "react";

function FunctionComponent() {
  const [counter, setCounter] = useState(0); //counter: 초기값 0으로 설정
  const onClick = () => {
    setCounter(counter + 1);
    console.log("클릭되었습니다");
  };
  return (
    <div>
      <h1>Hello World, Function Component</h1>
      <h5>{counter}</h5>
      <button onClick={onClick}>숫자 업</button>
    </div>
  );
}


export default FunctionComponent;

  코드를 하나하나 확인해보자.

import {  useState } from "react";

  이 코드는 react 내의 useState함수를 구조 분해 할당으로 import(가져오는) 코드이다.

 

const [counter, setCounter] = useState(0);

  이 코드는 [현재상태, setter함수]로 불러온 useState함수를 구조 분해 할당하는 코드이다.

  그리고, useState(0)은 0을 counter의 default값으로 지정한다는 의미이다.

 

  이후 여기서 설정한 setter함수인 setCounter를 통해

  1) counter의 state 값을 바꿔줄 수 있고,

  2) 변경한 이후에는 렌더링을 해줄 수 있다.

 

const onClick = () => { setCounter(counter + 1); console.log("클릭되었습니다"); };

  이 코드에서 앞서 말한 것처럼

  setCounter함수를 이용해 counter의 state값을 변경해준다.

  여기서는 버튼 클릭시 counter값이 +1이 되도록 이벤트를 설정했다.

 

<h5>{counter}</h5>

  이 코드는 counter 값(state)를 출력하는 코드이다.

  버튼이 클릭될 때 마다 +1씩 증가하는 counter값을 확인 할 수 있다.

 

<button onClick={onClick}>숫자 업</button>

  이 코드는 버튼이 클릭될 때 마다 onClick함수가 실행되도록 button에 onClick을 걸어준 코드이다. 

 

  여기서 주의할 점은 onClick = {onClick()} 처럼 함수명+괄호() 즉, 함수 자체를 전달하면 안된다.

  이유는 그렇게 되면 렌더링할 때마다 호출되기 때문이라고 한다.

  괄호를 빼고 작성해야 레퍼런스로만 적용된다고 한다.

  공식문서 >> https://ko.legacy.reactjs.org/docs/faq-functions.html

 

 나.클래스형 컴포넌트의 state

  먼저 잘 쓰이지 않는 constructor 매서드를 사용해 class형 컴포넌트를 작성해보면 아래와 같다.

 

   1)constructor 사용 (O)

import { Component } from "react";
 
class ClassComponent1 extends Component {
  constructor(props) {
    super(props);
 
    this.state = {
      counter: 0
    };
  }
 
  render() {
    const { counter } = this.state;
    return (
      <div>
        <h1>{counter}</h1>
        <button
          onClick={() => {
            this.setState({ counter: counter + 1 });
          }}
        >
          +1
        </button>
      </div>
    );
  }
}
 
export default ClassComponent1;

 

   이 코드는 컴포넌트의 생성자 매서드이다.

   constructor(props) { super(props); ~

   클래스형 컴포넌트에서 constructor를 작성할 때는 반드시 super(props)호출해야한다.

   이 함수가 호출되면 현재 클래스형 컴포넌트가 상속하고 있는

   리액트의 ClassComponent1클래스가 지닌 생성자함수를 호출한다.

 

this.state = { counter: 0 };

   super(props);의 다음 줄에서는 this.state값에 초깃값을 설정했다.

   counter의 초깃값으로 0을 설정했다.

 

render() { const { counter } = this.state; return ( ...

   render 함수에서 현재 state를 조회할 때는 this.state사용하면 된다.

   만약 reander 함수 내에 const { counter } = this.state; 이 코드를 작성하지 않으면,

   <h1>{counter}</h1> => <h1>{this.state.counter}</h1>로 작성해야한다.

 

<button onClick={() => { this.setState({ counter: counter + 1 }); }} > +1 </button>

   함수 내부에서 this.setState라는 함수를 사용해서 버튼 클릭시 마다

   state값을 변경하도록 했다.

 

   2)constructor 사용 (X)

   constructor 매서드를 선언하지 않고 state의 초깃값을 지정하는 방법은 아래와 같다.

   이 방식이 더 간편해서 자주 사용된다. 

import { Component } from "react";
 
class ClassComponent2 extends Component {
  state = {
    counter: 0,
  }
 
  render() {
    const { counter } = this.state;
    return ( ... );
  }
}
 
export default ClassComponent2;

 

   마지막으로 위 두 방법을 비교하면 다음과 같다.

 

constructor 유무 비교

 

 

 다.this.setState에 함수인자 전달

 

onClick={() => { this.setState({ counter: counter + 1 }); this.setState({ counter: counter + 1 });}}

  만약 위와 같이 onClick에 설정한 함수 내부에서 this.setState를 호출하면 어떻게될까?

  예상대로라면 +2가 되는 것이겠지만, 그렇지 않다.

 

  this.setState는 state를 비동기적으로 업데이트하므로, 바로 state값이 변경되지 않는다.

  이에 대한 해결책으로 this.setState를 사용할 함수를 인자로 넣어줄 있다.

 

this.setState((prevState, props) => {
    return {
      // 업데이트 하고 싶은 내용
    }
})

 

 this.setState의 인자로 함수를 넣어줄 때는 아래와 같은 형식으로 작성한다.

 여기서 prevState는 기존상태이고, props는 현재 지니고있는 props가리킨다.

 만약 업데이트하는 과정에서 props가 필요하지 않다면 생략해도 된다.



 기존 코드를 변경하면 아래와 같다. 위와 아래코드는 동일하지만 아래는 return대신 ({})을 사용해서 바로 객체를 반환한다.

<button
          onClick={() => {
            this.setState(prevState => {
              return {
                number: prevState.number + 1
              };
            });
 
            //위코드와 아래 코드는 완전히 똑같은 기능을 합니다.
            //아래 코드는 함수에서 바로 객체를 반환합니다.
 
            this.setState(prevState => ({
              number: prevState.number + 1
            }));
          }}
        >
          +1
</button>

  숫자가 2씩 증가한다.

 

 

728x90