본문 바로가기
웹 프로그래밍/JavaScript | TypeScript

리액트 공식문서 읽기 - 주요개념(Lifecycle)

by 청량리 물냉면 2024. 3. 18.
반응형

Lifecycle

const root = ReactDOM.createRoot(
  document.getElementById('root')
);

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  root.render(element);
}

setInterval(tick, 1000);

이전 섹션(엘리먼트 렌더링)에서 다루었던 시계 코드는 렌더링 된 출력값을 변경하기 위해 `root.render()`를 호출한다.

위 코드를 재사용 및 캡슐화 하면 아래와 같다.

const root = ReactDOM.createRoot(document.getElementById("root"));

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  root.render(<Clock data={new Date()} />);
}

setInterval(tick, 1000);

 

그러나 매초 UI가 업데이트 되지 않아 위 시계는 동작하지 않는다.

한번만 코드를 작성하고 `Clock`이 스스로 업데이트를 하도록 만들기 위해서는 `Clock` 컴포넌트에 `state`를 추가해야 한다.

`state`는 `props`와 유사하지만, 비공개이며 컴포넌트에 의해 완전히 제어된다는 특징을 가지고 있다.

 

함수에서 클래스로 변환하기

  1. React.Component를 extends하는 동일한 이름의 클래스 생성
  2. render() 메소드를 추가
  3. 함수의 내용을 render() 메서드 안으로 옮김
  4. render() 내용 안에 있는 props를 this.props로 변경
  5. 남아있는 빈 함수 선언 삭제
function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

⬇

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

 

render 메서드는 업데이트 발생 시마다 호출되지만, 같은 DOM 노드로 <Clock/>을 렌더링하는 경우 클래스의 단일 인스턴스만 사용된다(여러 개의 인스턴스가 생기지 않는다). 

이러한 특성을 기반으로, 로컬 state와 생명주기 메서드와 같은 부가적인 기능을 사용할 수 있게 된다.

 

클래스에 로컬 State 추가하기

date값을 props -> state로 이동시키기

const root = ReactDOM.createRoot(document.getElementById("root"));

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  root.render(<Clock data={new Date()} />);
}

setInterval(tick, 1000);


⬇ 기존 시계 코드를 아래와 같이 변경한다.

class Clock extends React.Component {
  constructor(props){
    super(props);
    this.state = {date: new Date()}
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Clock />);

 

 

생명주기 메서드를 클래스에 추가하기

위의 시계 프로그램에서 Clock이 처음 DOM에 렌더링되는 것을 React에서는 `마운팅`이라 한다.

반대로 Clock에 의해 생성된 DOM이 삭제되는 것을 `언마운팅`이라고 한다.

컴포넌트 클래스에서 특별한 메서드를 선언하여 컴포넌트가 마운트/언마운트 될 때 일부 코드를 작동시킬 수 있으며, 이러한 메서드들을 `생명주기 메서드`라고 부른다.

componentDidMount() {
}

componentWillUnmount() {
}

`componentDidMount()` 메서드는 컴포넌트 출력물이 DOM이 렌더링된 후에 실행된다.

시계 앱에서 타이머를 설정하여 실행시키려면 이 메서드에서 해당 작업을 수행한다.

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

`componentWillUnmount()` 메서드에는 타이머 삭제 코드를 넣어 생명주기를 관리한다. Clock 컴포넌트가 DOM으로부터 한번이라도 삭제된 적이 있다면 React는 타이머를 멈추기 위해 `componentWillUnmount()` 메서드를 호출한다.

componentWillUnmount() {
  clearInterval(this.timerID);
}

 

생명주기를 관리까지 추가한 코드는 아래와 같다.

class Clock extends React.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!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Clock />);
반응형