본문 바로가기

■ 프로그래밍/React

React Lifecycle(생명 주기)

리액트의 컴포넌트가 어떻게 실행되고, 어떤 순서로 호출되는지에 대해 알아보겠다. 

 

출처: react 홈페이지

생명주기 도표를 보면 더 자세히 볼 수 있다. 

 

컴포넌트는 '생성 => 업데이트 => 제거'의 생명 주기를 갖고 있다. 

아래 목록에서 자주 사용되는 생명주기 메소드는 색을 표시하겠다. 나머지는 상대적으로 덜 사용된다. 

 

마운트(생성)

컴포넌트의 인스턴스가 생성되어, DOM에 삽입될 때 순서대로 호출된다. 

- consturctor()

- static getDerivedStateFromProps()

- render()

- componentDidMount()

 

업데이트

props나 state가 변경되면 렌더(갱신)가 진행되며 순서대로 호출된다. 

- statis getDerivedStateFromProps()

- shouldComponentUpdate()

- render()

- getSnapshotBeforeUpdate()

- componentDidUpdate()

 

마운트 해제(제거)

아래 메소드는 컴포넌트가 DOM에서 제거될 때 호출된다. 

- componentWillUnmount()

 

 

위에 명시된 자주 사용되는 생명주기 메소드에 대해 간략한 소개를 하겠다. 

 

render()

클래스 컴포넌트에서 반드시 구현되어야 하는 유일한 메소드이다. 

 - 이 메소드가 호출되면, this.props와 this.state의 값을 활용하여 값을 반환한다. 

 - render() 함수는 컴포넌트의 state를 변경하지 않고, 호출될 때마다 동일한 결과를 반환하며 브라우저와 직접적인 상호작용을 하지 않는다. 

 

costructor(props)

메소드를 바인딩하거나 state를 초기화하는 작업이 없다면 constructor(생성자)가 없어도 된다. 

 - react 컴포넌트의 생성자는 해당 컴포넌트가 마운트되기 전에 호출된다.

 - 생성자를 구현하면, this.props가 생성자 내에서 정의되도록 super(props)를 호출해야 한다. 

 - state의 값을 변경하고자 한다면, constructor() 외부에서 this.setState()를 통해 수정해야 한다. 

 

componentDidMount()

컴포넌트가 마운트 된 직후에 호출된다.

 - DOM 노드가 있어야 하는 초기화 작업이 이루어지면 좋다. 

 - 외부에서 데이터를 불러와야 한다면, 네트워크 요청을 보내기 좋은 위치이다. 

 

componentDidUpdate()

갱신(렌더)가 일어난 직후 호출되며, 최초 렌더링에서는 호출되지 않는다. 

 

componentWillUnmount()

컴포넌트가 마운트 해제되어 제거되기 직전에 호출된다. 

 - 타이머 제거, 네트워크 요청 취소, componentDidMount()에서 생성된 작업 등을 정리할 때 사용된다.

 - 실행 직후, 컴포넌트는 렌더링 되지 않으므로, setState()를 호출하면 안된다. 

 

 

===

 

위의 내용을 토대로 이전글(2020/04/12 - State)의 시각이 실시간으로 바뀌도록 만들어 보자.

 

Clock이 처음 DOM에 렌더링 될 때마다 타이머를 설정(마운트)하고, DOM이 삭제될 때마다 타이머를 해제(제거)한다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
 
  componentDidMount() {
  }
 
  componentWillUnmount() {
  }
 
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
cs

 

그러려면 위에서 나온 componentDidMount()와 componentWillUnmount() 메소드를 추가해준다. 

 

그 후, 맨 처음 함수로 이를 생성했을 때, 1초마다 실행시켜주는 setInterval() 함수를 호출한다.

1
2
3
4
5
6
componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
}
cs

setInterval 함수는 timer의 id를 리턴하기 때문에 this.timerID에 저장했다. 

그리고 unmount 될 때, clearInterval 함수로 지금 만든 timer를 삭제해준다. 

1
2
3
componentWillUnmount() {
    clearInterval(this.timerID);
}
cs

마지막으로 해당 값이 바뀌었다는 것을 컴포넌트에게 알려주기 위해 this.setState()로 업데이트 한다. 

 

 

완성된 코드

See the Pen Hello World in React by Dan Abramov (@gaearon) on CodePen.

Clock 호출 순서

1. <Clock />이 렌더 되면서, Clock 컴포넌트의 constructor 호출되고, 현재 시각을 표시해야하기 때문에 현재 시각이 포함된 객체로 this.state 초기화

2. Clock 컴포넌트를 render() 하고, 화면에 표시되어야 할 것을 출력

3. Clock 출력 값이 DOM에 삽입되면서, componentDidMount() 호출. 그 안에서 매초 컴포넌트의 tick() 호출을 위한 타이머를 설정하도록 브라우저에 요청

4. 매초마다 브라우저가 tick() 호출, 안의 setState()로 매초마다 업데이트 진행되고, 업데이트 될 때마다 렌더 되면서 바뀐 값이 화면에 출력

5. Clock 컴포넌트가 DOM으로부터 한 번이라도 삭제된 적이 있다면, 리액트는 타이머를 멈추기 위해 componentWillUnmount() 호출

 

'■ 프로그래밍 > React' 카테고리의 다른 글

Props, State, constructor()  (0) 2020.04.14
Default Export, Named Export  (0) 2020.04.13
State  (0) 2020.04.12
Props  (0) 2020.04.12
[React/에러] Module not found: Can't resolve './node_modules/react'  (0) 2020.04.12