본문 바로가기
Study/React

[리액트(React)] 4. 컴포넌트(Component) - 클래스

by _temp 2022. 1. 23.

리액트의 컴포넌트에는 클래스 컴포넌트와 함수 컴포넌트가 있다.

위 캡처본에 우측에 HOOK이라고 따로 빠져나온 게 있는데 이는 리액트 훅이라고 함수 컴포넌트를 위해 도입된 것이라서 따로 빼서 만든 것 같다. 리액트는 함수 컴포넌트를 밀고 있고, 다들 함수 컴포넌트를 사용하는 느낌이지만 기존에 이미 만들어져서 운영되고 있는 사이트들은 클래스 컴포넌트를 사용하고 있어서 둘 다 잘 알고 있어야 할 듯하다.

 

그래서 컴포넌트 부분만 리액트 공식문서의 순서대로가 아닌 클래스 컴포넌트 -> 함수 컴포넌트 순으로 공부를 할 예정이다!


클래스 컴포넌트

- React.Component를 상속해야 한다

// App.jsx
import React, {Component} from 'react';
import './App.css'
import Greeting from './component/greeting'

class App extends Component {
  render() {
    return (
      <Greeting name="2HS" job="Student"/>
    );
  }
}

export default App

- 클래스 컴포넌트의 Props

부모 컴포넌트가 전달해준 값을 this.popps로 접근할 수 있다.

// components/greeting.jsx
import React, { Component } from 'react';

class Greeting extends Component {
  render() {
    return (
      <div>
        <h1>{this.props.name}</h1>
        <h1>{this.props.job}</h1>
      </div>
    );
  }
}

export default Greeting;

- 클래스 컴포넌트의 State

클래스 컴포넌트는 항상 props로 기본 constructor를 호출해야 합니다. 라고 공식문서에 적혀 있다.

// components/greeting.jsx
import React, { Component } from 'react';

class Greeting extends Component {
  constructor(props){
  	// 생성자 호출
    super(props);
    // state 정의
    this.state = {
      num : 0
    };
  }

  render() {
    return (
      <div>
        <h1>이름 : {this.props.name}</h1>
        <h1>직업 : {this.props.job}</h1>
        <h1>인사 횟수 : {this.state.num}</h1>
        <button>인사하기</button>
      </div>
    );
  }
}

export default Greeting;

더 찾아보니 constructor 없이도 state만을 사용해서 사용할 수도 있었다.

// components/greeting.jsx
import React, { Component } from 'react';

class Greeting extends Component {
  state {
    num : 0
  }

  render() {
    return (
      <div>
        <h1>이름 : {this.props.name}</h1>
        <h1>직업 : {this.props.job}</h1>
        <h1>인사 횟수 : {this.state.num}</h1>
        <button>인사하기</button>
      </div>
    );
  }
}

export default Greeting;

 

- 이벤트와 State 업데이트 (setState)

직접 state를 바꾸지 말고 setState를 통해서 바꾸도록 하자

state 업데이트는 비동기적일 수도 있어서 직접 바꾸는 것은 에러 위험이 크다

// components/greeting.jsx
import React, { Component } from 'react';

class Greeting extends Component {
  constructor(props){
    // 생성자 호출
    super(props);
    this.state = {
      num : 0
    };
  }

  greet = () => {
    const num = this.state.num + 1
    this.setState({ num })
    // 이름이 같으면 생략가능
    // this.setState({ num : num })
  }

  render() {
    return (
      <div>
        <h1>이름 : {this.props.name}</h1>
        <h1>직업 : {this.props.job}</h1>
        <h1>인사 횟수 : {this.state.num}</h1>
        <button onClick={this.greet}>인사하기</button>
      </div>
    );
  }
}

export default Greeting;

 

- 생명 주기 메서드

componentDidMount() : component가 mount 됐을 때 실행하는 메서드

componentDidUpdate() : component가 update 됐을 때 실행하는 메서드

이외에도 componentWillUnmount() 등등 여러 생명주기 메서드가 있고 이제는 사용을 권장하지 않는 메서드들이 있으니 확인해보자

// components/greeting.jsx
import React, { Component } from 'react';

class Greeting extends Component {
  constructor(props){
    // 생성자 호출
    super(props);
    this.state = {
      num : 0
    };
  }

  componentDidMount() {
    console.log('인사완료!')
  }
  componentDidUpdate() {
    console.log('인사완료!')
  }

  greet = () => {
    const num = this.state.num + 1
    this.setState({ num })
    // 이름이 같으면 생략가능
    // this.setState({ num : num })
  }


  render() {
    return (
      <div>
        <h1>이름 : {this.props.name}</h1>
        <h1>직업 : {this.props.job}</h1>
        <h1>인사 횟수 : {this.state.num}</h1>
        <button onClick={this.greet}>인사하기</button>
      </div>
    );
  }
}

export default Greeting;