[REACT]리액트를 다루는 기술 - state

koseony·2022년 5월 24일

REACT

목록 보기
6/6
post-thumbnail

state

❗클래스 컴포넌트 기준으로 작성했습니다.

리액트에서 state는 컴포넌트 내부에서 바뀔 수 있는 값을 의미합니다. props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이며, 컴포넌트 자신은 해당 props를 읽기 전용으로만 사용할 수 있습니다.

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

import React, { Component } from "react";

export default class Counter extends Component {
  constructor(props) {
    super(props);
    // state의 초깃값 설정하기
    this.state = {
      number: 0,
    };
  }
  render() {
    const { number } = this.state; //state를 조회할 때는 this.state로 조회합니다.
    return (
      <div>
        <h1>{number}</h1>
        <button
          // onClick을 통해 버튼이 클릭되었을 때 호출할 함수를 지정합니다.
          onClick={() => {
            // this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다.
            this.setState({ number: number + 1 });
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

위 코드에서 각 코드가 어떤 역할을 하는지 알아보겠습니다.
컴포넌트에 state를 설정할 때는 다음과 같이 constructor 메서드를 작성하여 설정합니다.

constructor(props) {
  super(props);
  // state의 초깃값 설정하기
  this.state = {
    number: 0,
  };
}

이는 컴포넌트의 생성자 메서드입니다.
constructor를 작성할 대는 반드시 super(props)를 호출해 주어야 합니다. 이 함수가 호출되면 현재 클래스형 컴포넌트가 상속받고 있는 리액트의 Component 클래스가 지닌 생성자가 함수를 호출해 줍니다.
그 다음에는 this.state값에 초기값을 설정해 주었습니다. 컴포넌트의 state는 객체 형식이어야 합니다.

render 함수를 알아봅시다.

render() {
  const { number } = this.state; //state를 조회할 때는 this.state로 조회합니다.
  return (
    <div>
      <h1>{number}</h1>
      <button
        // onClick을 통해 버튼이 클릭되었을 때 호출할 함수를 지정합니다.
        onClick={() => {
          // this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다.
          this.setState({ number: number + 1 });
        }}
      >
        +1
      </button>
    </div>
  );
}

render 함수에서 현재 state를 조회할 때는 this.state를 조회하면 됩니다.
그리고 button안에 onClick이라는 값을 props로 넣어 주었는데, 이는 버튼이 클릭될 때 호출 시킬 함수를 설정할 수 있게 해줍니다. 이를 이벤트를 설정한다고 합니다.
함수 내부에서는 this.setState라는 함수를 사용했는데 이 함수가 state 값을 바꿀 수 있게 해줍니다.

코드를 실행해 보겠습니다.

버튼을 클릭하면 setState에서 state값을 바꿔 줍니다.

1-1. state를 constructor에서 꺼내기

constructor 메서드를 선언하지 않고 state의 초기값을 지정해 줄 수 있습니다.

import React, { Component } from "react";

export default class Counter extends Component {
  state = {
    number: 0,
    fixedNumber: 0,
  };

  render() {
    const { number, fixedNumber } = this.state; //state를 조회할 때는 this.state로 조회합니다.
    return (
      <div>
        <h1>{number}</h1>
        <h2>바뀌지 않는 값: {fixedNumber}</h2>
        <button
          // onClick을 통해 버튼이 클릭되었을 때 호출할 함수를 지정합니다.
          onClick={() => {
            // this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다.
            this.setState({ number: number + 1 });
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

1-2. this.setState에 객체 대신 함수 인자 전달하기

this.setState를 사용하여 state 값을 업데이트할 때는 상태가 비동기적으로 업데이트 됩니다. 만약 다음과 같이 onClick에 설정한 함수 내부에서 this.setState를 두 번 호출하면 어떻게 될까요?

onClick={() => {
  // this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다.
  this.setState({ number: number + 1 });
  this.setState({ number: number + 1 });
}}

this.setState를 두 번 사용했는데도 불구하고 버튼을 클릭할 때 숫자가 1씩 더해집니다. this.setState를 사용한다고 해서 state 값이 바로 바뀌지는 않기 때문입니다.
이에 대한 해결책은 this.setState를 사용할 때 객체 대신에 함수를 인자로 넣어주는 것입니다.
this.setState의 인자로 함수를 넣어줄 때는 코드를 다음과 같은 형식으로 작성합니다.

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

여기서 prevState는 기존 상태이고, props는 현재 지니고 있는 props를 가리킵니다. 만약 업데이트 과정에서 props가 필요하지 않다면 생략해도 됩니다.

<button
  // onClick을 통해 버튼이 클릭되었을 때 호출할 함수를 지정합니다.
  onClick={() => {
    // this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다.
    this.setState((prevState) => {
      return {
        number: prevState.number + 1,
      };
    });
    // 위 코드와 아래 코드는 완전히 똑같은 기능을 합니다.
    // 아래 코드는 함수에서 바로 객체를 반환한다는 의미입니다.
    this.setState((prevState) => {
      return {
        number: prevState.number + 1,
      };
    });
  }}
>
  +1
</button>

위 코드처럼 작성하면 클릭했을 때 +2씩 올라갑니다.

1-3. this.setState가 끝난 후 특정 작업 실행하기

setState를 사용하여 값을 업데이트하고 난 다음에 특정 작업을 하고 싶을 때는 setState의 두 번째 파라미터로 콜백(callback) 함수를 등록하여 작업을 처리할 수 있습니다.

import React, { Component } from "react";

export default class Counter extends Component {
  state = {
    number: 0,
    fixedNumber: 0,
  };

  render() {
    const { number, fixedNumber } = this.state; //state를 조회할 때는 this.state로 조회합니다.
    return (
      <div>
        <h1>{number}</h1>
        <h2>바뀌지 않는 값: {fixedNumber}</h2>
        <button
          // onClick을 통해 버튼이 클릭되었을 때 호출할 함수를 지정합니다.
          onClick={() => {
            // this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다.
            this.setState({ number: number + 1 }, () => {
              console.log("방금 setState가 호출되었습니다.");
              console.log(this.state);
            });
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

number를 +1 해주고 그다음 콘솔을 찍어주었습니다.

profile
프론트엔드 개발자

0개의 댓글