TIL050 라이프 사이클 이슈와 그 해결책

Somi·2021년 7월 18일
0

React

목록 보기
9/11
post-thumbnail


출처: http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

라이프 사이클이란

LifeCycle Method 는 한국어로 "생명주기 메서드" 라고 부른다. 생명주기 메서드는 컴포넌트가 브라우저상에 나타나고, 업데이트되고, 사라지게 될 때 호출되는 메서드들이다.

Lifecycle 기본 순서

마운트 될 때 발생하는 생명주기는 아래와 같다.
<---마운트--->
1. constructor
2. render
3. componentDidMount
<---업데이트--->
4. (fetch 완료)
5. (setState)
6. render
7. componentDidUpdate (5번에서 setState 되었기 때문에 컴포넌트 업데이트 발생)
<---언마운트--->
8. componentWillUnmount

constructor

constructor는 컴포넌트 생성자 매서드이다. 컴포넌트가 만들어지면 가장 먼저 실행된다.

render

컴포넌트를 렌더링하는 메서드이다.

componentDidMount

첫번째 렌더링을 마치고 나면 호출되는 메서드 이다. 이 메서드가 호출되는 시점에는 컴포넌트가 화면에 나타난 상태이다.

componentDidUpdate

componentDidUpdate는 리렌더링을 마치고, 화면에 원하는 변화가 모두 반영되고 난 뒤 호출되는 메서드이다.

componentWillUnmount

언마운트라는것은, 컴포넌트가 화면에서 사라지는것을 의미한다. 언마운트에 관련된 생명주기 메서드는 componentWillUnmount 하나이다. 이는 컴포넌트가 화면에서 사라지기 직전에 호출된다.

라이프 사이클 이슈


라이프 사이클 메서드들의 기본 호출 순서를 다시 살펴보면 렌더가 두번 일어난다는 사실을 알 수 있다. CDM안 fetch함수를 기준으로, 한번은 이전에 한번은 이후에 호출된다.

import React, { Component } from "react";

export default class FetchError extends Component {
  constructor() {
    super();
    this.state = {
      data: {},
    };
  }

  componentDidMount() {
    fetch("/lifecycle.json")
      .then((res) => res.json())
      .then((res) => {
        this.setState({ data: res });
      });
  }

  render() {
    return (
      <div>
        {this.state.data.message.map((msg) => {
          return <li>{msg}</li>;
        })}
      </div>
    );
  }
}

위 코드에서 this.state.data.message.map부분을 보면, 첫번째 렌더에서는 초기값인 빈객체를 가지고, 두번째 렌더에서는 빈객체에 서버에서 받아온 배열이 들어오게 된다. 두번째 렌더에서는 잘 작동하겠지만, 서버에서 값을 받아오기 전인 첫 번째 렌더에서는 array가 아닌 object 타입에 map 함수를 실행시키고 있으므로 타입 에러를 발생시킨다!

라이프 사이클 이슈 해결하기

이러한 라이프 사이클 이슈를 해결하기 위해 조건부 렌더링이라는 것이 존재한다. 컴포넌트 함수 내부에서 특정 값에 따라 선택적으로 렌더링하는 것을 조건부 렌더링이라고 한다.

조건부 렌더링을 구현하기 위해서는 삼항 연산자 혹은 && 연산자를 사용할 수 있다. 삼항 연산자 의 경우 조건의 true / false 에 따라 각기 다른 UI 를 렌더링 할 때 사용하고, && 연산자 의 경우 조건이 true 일때만 특정 UI 를 렌더링 하고 false 일때는 아무것도 렌더링 하지 않도록 할 때 사용한다.

이를 더 깔끔하게 하기 위해서 자주 사용하게 되는 함수(validation 함수 등)는 다른 파일에 모아서 작성해두면 좋다!

export function isValidObject(obj) {
  return !!Object.keys(obj).length;
}
// 호출할때 
import * as isValidObject from "./InputValidation.js";

const isValidObject = isValidObject.isValidObject();

0개의 댓글