본문 바로가기
Frontend/React

React 클래스형 컴포넌트 개념과 사용 방법

by Forsaken Developer 2023. 2. 3.
728x90
728x90

React 클래스형 컴포넌트 개념과 사용 방법

컴포넌트를 만들때는 function 키워드나 화살표 함수표현을 사용하여 화면에 렌더링할 jsx 코드를 반환하는 자바스크립트 함수를 사용한다.

대부분의 리액트 프로젝트에서는 이러한 함수형 컴포넌트만을 사용할 것이다.

컴포넌트를 정의하는 또 다른 방법이 클래스형 컴포넌트이다.

함수형 컴포넌트를 통해 만들 수 있는 건 클래스형 컴포넌트로도 만들 수 있다.

클래스 기반 컴포넌트가 존재하는 이유는 리액트 16.8 이전에 상태를 처리하고 사이드 이펙트를 다룰 때 클래스 기반 컴포넌트를 사용했어야 했고 리액트 16.8 이전에는 함수 컴포넌트에서는 상태 변경이 불가능했고 사이드이펙트 역시 다룰 수 없었기때문이다.

리액트 16.8 이후 리액트에서 리액트 훅이라는 훅에 대한 개념을 도입한 뒤로 함수형 컴포넌트를 사용하기 시작했다.

UseState나 useEffect같은 것들은 예전에는 클래스형 컴포넌트에서만 가능했던 것들이다.

클래스형 컴포넌트 props

const User = (props) => {
  return <li>{props.name}</li>;
};

export default User;

함수형 컴포넌트로 정의한 User 컴포넌트를 클래스형 컴포넌트로 바꿀 수 있다.

import Component from "react";

class User extends Component {
  constructor() {}
  render() {
    return <li className={classes.user}>{this.props.name}</li>;
  }
}
export default User;

자바스크립트의 class 예약어를 통해서 클래스를 정의하고 메소드를 추가하는 것으로 시작한다.

먼저 초기화 작업을 하는 생성자 메소드를 추가할 수 있다.

render() 메소드는 리액트에 필요한 특정 메소드로 리액트가 jsx 코드 안에 컴포넌트가 사용된 것을 확인하면 그때 호출하는 메소드이다.

이 render() 메소드 안에는 렌더링할 것을 알려주는 반환값이 필요하며 함수형 컴포넌트에서의 반환 문장과 동일하다.

함수형 컴포넌트에서는 props를 매개변수로서 전달받고 리액트가 자동으로 전달해준다.

하지만 클래스형 컴포넌트에서는 render() 메소드는 props을 받지않는다.

React에서 Component를 import하고 extends로 Component를 상속받는다.

Component를 상속하여 예약어 this를 통해서 컴포넌트로 받은 모든 props에 접근할 수 있게 된다.

함수형 컴포넌트가 조금 더 깔끔하고 이 때문에 사람들이 함수형을 더 선호한다.

그 외에는 모든 것이 같고 클래스형 컴포넌트는 함수형 컴포넌트와 함께 작업이 가능하다.

클래스형 컴포넌트 state

클래스 컴포넌트의 상태 관리 방법이 지금과는 완전히 달랐다.

리액트 16.8 버전부터 훅이 도입되면서 useState 훅을 통해 상태와 함수형 컴포넌트를 관리할 수 있게 되었다.

16.8 버전 이전에는, 클래스 컴포넌트만이 상태를 관리할 수 있는 유일한 컴포넌트였다.

기본적으로 2가지 작업을 해야 하는데 초기화와 상태 정의 이다.

초기화는 useState 첫 호출시 하는 것과 같고 상태 정의는필요할 때 업데이트하는 것이다.

클래스 컴포넌트에서 상태를 정의할 때는 생성자를 사용한다.

생성자 함수는 리액트가컴포넌트로 사용되는 클래스를 만날 때 자동적으로 호출된다.

함수형 컴포넌트에서는 상태는 boolean이나 문자열,숫자,객체와 같이 어느 형태든 될 수 있지만 클래스 컴포넌트에서는 상태를 하나의 상태 객체로 만들기 때문에 상태는 항상 객체이다.

상태를 변경하고자 할 때에는 this.setState 메소드를 사용하며 기존의 상태를 오버라이드하지 않고

리액트가 백그라운드에서 현재 존재하는 상태와 여기에 전달하려는 객체를 병합한다.

이는 useState와는 분명 다른데 상태 갱신 함수를 호출하게 되면 새로운 상태를 만들기 위해 실행하는 함수가 아니라면 기존의 상태를 갱신 함수에 전달한 값으로 오버라이드하기 때문이다.

또한 useState와 마찬가지로 새로운 상태가 이전 상태에 의존한다면 갱신 함수를 setState에 전달한다.

class Users extends Component {
  constructor() {
    super();
    this.state = {
      showUsers: true,
    };
  }

  toggleUsersHandler() {
    this.setState((curState) => {
      return { showUsers: !curState.showUsers };
    });
  }

  render() {
    const usersList = (
      <ul>
        {this.props.users.map((user) => (
          <User key={user.id} name={user.name} />
        ))}
      </ul>
    );

    return (
      <div>
        <button onClick={this.toggleUsersHandler.bind(this)}>
          {this.state.showUsers ? "Hide" : "Show"} Users
        </button>
        {this.state.showUsers && usersList}
      </div>
    );
  }
}
export default Users;
728x90
반응형

댓글