Skip to main content

Class Component

  • 리액트는 훅이 나오기 전까지 상태관리는 클래스 컴포넌트로 만들어 구성하였다.
  • React Class는 클래스 생명 주기를 가지고 있다.
  • rcc 타이핑 후 enter를 누르면 클래스 컴포넌트가 만들어진다.
export default class ClassComponent extends Component {
constructor(props) {
super(props)
this.state = { date: new Date() }
}

componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
)
}

componentWillUnmount() {
clearInterval(this.timerID)
}

tick() {
this.setState({
date: new Date()
})
}

render() {
return (
<div>
<h1>Hello, World! It's the Class</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
)
}
}
  • constructor() 말 그대로 생성자를 의미한다.
    • 기본 적인 상태 초기화 등을 여기서 진행한다.
  • componentDidMount() 컴포넌트가 생성되면 실행된다.
    • 뷰 생성후 호출되어야 하는 작업들을 여기서 처리한다.
  • componentWillUnmount() 컴포넌트가 사라지기 전에 호출된다.
    • deinit 할때 리셋 해주어야 할 작업들을 처리한다.
  • render() 클래스 컴포넌트의 뷰를 랜더하는 함수이다.
    • React.Component의 하위 클래스에서 반드시 정의해야하는 메서드이다.
  • class component에서는 this를 통에 상태에 접근한다.
  • 상태를 변경할 때에는 set 함수를 사용한다.
  • 클래스에서 State 사용시 주의 사항
    • 직접 State를 수정하면 안된다.
      • 렌더링이 비정상적으로 작동할 수 있다.
    • State는 비동적이다.
    • State 업데이트는 병합된다.

컴포넌트 생명주기

  • 모든 컴포넌트는 여러 종류의 "생명주기 메서드"를 가지며, 이 메서드를 오버라이딩하여 특정 시점에 코드가 실행되도록 설정할 수 있다.

마운트

  • 인스턴스가 생성되어 DOM 상에 삽입될 떄에 순서대로 호출된다.
    • constructor()
    • static getDeriviedStateFromProps()
    • render()
    • componentDidMount()

업데이트

  • props 또는 state가 변경되면 갱신이 발생한다.
  • 컴포넌트가 다시 렌더링 될 때 순서대로 호출된다.
    • static getDeriviedStateFromProps()
    • shouldComponentUpdate()
    • render()
    • getSnapshotBeforeUpdate()
    • componentDidUpdate()

마운트 해제

  • 컴포넌트가 DOM 상에서 제거될 때에 호출된다.
    • componentDidUpdate()

오류처리

  • 자식 컴포넌트를 렌더링 하거나, 생명주기 메서드를 호출하거나, 생성자 메서드를 호출하는 과정에서 오류가 발생했을 때 호출된다.
    • static getDerivedStateFromError()
    • componentDidCatch()

render()

  • render() 메서드는 클래스 컴포넌트에서 반드시 구현돼야하는 유일한 메서드이다.
  • render 함수는 순수해야 한다. 즉, 컴포넌트의 state를 변경하지 않고, 호출될 떄마다 동일한 결과를 반환해야하며, 브라우저와 직접적으로 상호작용하지 않는다.

Constructor()

  • 메서드를 바인딩하거나 state를 초기화 하는 작업이 없다면, 해당 React 컴포넌트에는 생성자를 구현하지 않아도 된다.
  • 컴포넌트 생성자를 구현할 때에는 super(props)를 호출해야만 한다.
  • 생성자의 목적
    • this.state에 객체를 할당하여 지역 state를 초기화
    • 인스턴스에 이벤트 처리 메서드를 바인딩
  • 내부에서 setState()를 호출하면 안된다.
  • 지역 state가 필요하면 생성자 내에서 아래와 같이 처리한다.
constructor(props){
super(props)
this.state = { counter : 0}
}
  • this.state를 직접 할당할 수 있는 유일한 곳이다.
  • state에 props를 복사하면 안된다.

compoenetDidMount()

  • 컴포넌트가 마운트된 직후, 즉 트리에 삽입된 직후에 호출된다.
  • DOM 노드가 있어야 하는 초기화 작업은 여기서 이루어 진다.
  • 외부에서 데이터를 불러와야 한다면 이곳에서 네트워크 요청을 하면 된다.
  • 데이터 구독을 위한 최적의 장소이다.
  • 데이터 구독이 이루어졌다면 componentWillUnmound()에서 구독 해제 작업이 필요하다.

componentDidUpdate()

  • 갱신이 일어난 직후에 호출된다.
  • 최초 렌더링에는 호출되지 않는다.
  • 컴포넌트가 갱신되었을 때, DOM을 조정하기 위하여 이 메서드를 활용하면 좋다.
componentDidUpdate(prevProps) {
// 전형적인 사용 사례 (props 비교를 잊지 마세요)
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}

componentWillUnmound()

  • 컴포넌트가 마운트 해제되어 제거되기 직전에 호출된다.
  • 타이머 제거, 네트워크 요청 취소, componentDidMount() 내에서 생성된 구독 해제 등 필요한 모든 정리 작업을 수행한다.

생명주기 이해하기

import React, { Component } from "react";

export default class ClassLCComponent extends Component {
constructor(props) {
super(props);
console.log("constructor")
this.state = { date: new Date() };
this.handleClick = this.handleClick.bind(this)
}

componentDidMount() {
console.log("componentDidMount")
this.timerID = setInterval(() => {
this.tick()
}, 10000)
}

componentDidUpdate() {
// console.log("componentDidUpdate")
}

componentWillUnmount() {
console.log("componentWillUnmount")
clearInterval(this.timerID)
}

tick() {
this.setState({date: new Date()})
}

handleClick() {
alert(this.state.date)
}

render() {
console.log("render")
return <div>
<h1 onClick={this.handleClick}>Hello, LifeCycle!</h1>
<h2>{this.state.date.toLocaleDateString()}</h2>

</div>;
}
}
  • 사용자 함수가 this.state에 접근해야만 할 떄에는 생성자에서 바인딩을 해주어야만 한다.
  constructor(props) {
this.handleClick = this.handleClick.bind(this)
}

handleClick() {
alert(this.state.date)
}
  • 단, arrow function일 경우에는 바인딩이 필요없다.

참조