Logo

React Hooks: useState 사용법

컴포넌트의 상태 관리를 위해 React Hooks에서 제공되는 setState() 함수에 대해서 알아보도록 하겠습니다.

this.state - 클래스 기반 상태 관리

React Hooks가 나오기 전에는 컴포넌트의 상태 관리를 하려면 클래스 기반 React 컴포넌트를 작성해야 했습니다. 대표적으로 상태 관리가 필요한 경우인, 사용자 입력 양식을 위한 컴포넌트를 작성한다고 생각해보겠습니다.

아래 예제 코드는 사용자의 이름과 이메일을 입력받기 위한 전형적인 React 컴포넌트입니다. 클래스 컴포넌트의 this.state 필드에 이름과 이메일 값을 저장해두고 사용자가 이 값을 변경할 때 마다 이 값이 갱신되고 다시 화면에 반영이 됩니다.

import React, { Component } from "react";

class UserFormClass extends Component {
  state = { name: "", email: "" };

  handleClick = ({ target: { name, value } }) => {
    this.setState({ [name]: value });
  };

  render() {
    const { name, email } = this.state;

    return (
      <>
        <label>
          Name:
          <input
            type="text"
            name="name"
            value={name}
            onChange={this.handleClick}
          />
        </label>
        <label>
          Email:
          <input
            type="email"
            name="email"
            value={email}
            onChange={this.handleClick}
          />
        </label>
      </>
    );
  }
}

많은 React 개발자들은 이렇게 간단한 상태 관리 조차도 클래스 기반 컴포넌트로 작성해야 한다는 점에 대해서 불평했었습니다. 클래스 기반 컴포넌트는 함수 기반 컴포넌트에 비해 복잡하고 따라서 오류가 발생하기 쉽고 유지 보수가 힘들기 때문입니다.

setState() - 함수 기반 상태 관리

React Hooks에서 제공하는 useState() 함수를 사용해서 위의 클래스 기반 컴포넌트를 함수 기반으로 재작성해보았습니다. setState() 함수는 배열을 리턴하는데 첫 번째 원소는 상태 값을 저장할 변수이고 두번 째 원소는 해당 상태 값을 갱신할 때 사용할 수 있는 함수입니다. 그리고 setState() 함수에 인자로 해당 상태의 초기 값을 넘길 수 있습니다.

const [<상태 값 저장 변수>, <상태 값 갱신 함수>] = useState(<상태 초기 값>);

상태 값 갱신 함수를 사용하지 않고 직접 변수를 다른 상태 값으로 할당하면 화면에 반영되지 않으니 주의해야 합니다. 클래스 컴포넌트에서 this.state를 갱신할 때 반드시 this.setState()를 사용해야하는 것과 같은 이치입니다.

import React, { useState } from "react";

function UserFormFunction() {
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");

  return (
    <>
      <label>
        Name:
        <input
          type="text"
          name="name"
          value={name}
          onChange={({ target: { value } }) => setName(value)}
        />
      </label>
      <label>
        Email:
        <input
          type="email"
          name="email"
          value={email}
          onChange={({ target: { value } }) => setEmail(value)}
        />
      </label>
    </>
  );
}

마치면서

본 예제 코드는 간단해서 코드가 많이 단순해지는 것처럼 보이지 않지만, 실제 프로젝트에서에서 사용되는 복잡한 클래스 컴포넌트를 useState()를 사용해서 함수 컴포넌트로 리팩토링을 해보면 그 진가를 확인하실 수 있으실 것입니다.

포스팅에서 작성된 전체 코드는 아래를 참고바랍니다.

React Hooks 관련 포스팅