React 생명 주기(life cycle)

Jeris·2023년 5월 1일
0

코드잇 부트캠프 0기

목록 보기
73/107
post-thumbnail

1. React life cycle

React 생명 주기(life cycle)란?

  • React에서 컴포넌트의 생성, 업데이트 및 제거될 때 특정 시점에서 자동으로 호출되는 함수들을 정의할 수 있는 메서드입니다.
  • 컴포넌트의 state 변화를 추적하고, 화면에 렌더링되는 요소들을 최적화해줍니다.
  • 일반적인 life cycle
  • 덜 일반적인 life cycle

클래스 컴포넌트에서 사용되는 생명 주기 메서드

  • Mounting 아래 메서드들은 컴포넌트의 인스턴스가 생성되어 DOM 상에 삽입될 때에 순서대로 호출됩니다.

    • constructor()
      • 컴포넌트가 생성될 때 호출되며, 초기 상태를 설정하거나 메서드를 바인딩합니다.
      • 보통 아래의 두 가지 목적을 위하여 사용됩니다.
        • this.state에 객체를 할당하여 local state를 초기화
        • 인스턴스에 event handler를 바인딩
      • React.Component를 상속한 컴포넌트의 생성자를 구현할 때에는 다른 구문에 앞서 super(props)를 호출해야 합니다. 그렇지 않으면 this.props가 생성자 내에서 정의되지 않아 버그로 이어질 수 있습니다.
      • constructor() 내부에서 setState()를 호출하면 안 됩니다. 컴포넌트에 local state가 필요하다면 생성자 내에서 this.state에 초기 state 값을 할당하면 됩니다.
    • static getDerivedStateFromProps()
      • 최초 마운트 시와 갱신 시 모두에서 render 메서드를 호출하기 직전에 호출되며, 컴포넌트의 초기 state를 갱신하기 위해 사용됩니다.
    • render()
      • 컴포넌트가 생성되거나 업데이트될 때마다 호출되며, 컴포넌트의 UI를 렌더링합니다.
      • 클래스 컴포넌트에서 반드시 구현돼야하는 유일한 메서드입니다.
      • React element, array와 Fragment, Portal, 문자열과 숫자, Booleans or null or undefined 중 하나를 반환해야 합니다.
    • componentDidMount()
      • 컴포넌트가 마운트되고 DOM에 삽입된 후 호출되며, 외부 데이터를 불러오거나 DOM 노드가 있어야 하는 초기화 작업이 이루어집니다.
      • 데이터 subscriptions가 이루어졌다면 componentWillUnmount()에서 unsubscribe해야 합니다.
  • Updating props 또는 state가 변경되면 갱신이 발생합니다. 아래 메서드들은 컴포넌트가 다시 렌더링될 때 순서대로 호출됩니다.

    • static getDerivedStateFromProps()
    • shouldComponentUpdate()
      • state 또는 props의 변화가 컴포넌트의 출력 결과에 영향을 미치는지 여부를 React가 알 수 있게 해줍니다.
      • 기본 동작은 매 state 변화마다 다시 렌더링을 수행하는 것이며, 대부분의 경우 기본 동작에 따라야 합니다.
    • render()
    • getSnapshotBeforeUpdate()
      • 가장 마지막으로 렌더링된 결과가 DOM 등에 반영되기 전에 호출되며, 컴포넌트가 DOM으로부터 스크롤 위치 등과 같은 정보를 이후 변경되기 전에 얻을 수 있게 해줍니다.
    • componentDidUpdate()
      • 컴포넌트의 업데이트가 완료된 후에만 호출되며, 컴포넌트가 갱신되었을 때 DOM을 조작하기 위하여 이 메서드를 활용 할 수 있습니다.
      • setState()를 즉시 호출할 수도 있지만, 조건문으로 감싸지 않으면 무한 반복이 발생할 수 있다는 점에 주의해야 합니다.
  • Unmounting 컴포넌트가 DOM에서 제거될 때 실행됩니다.

    • componentWillUnmount()
      • 컴포넌트가 DOM에서 제거되기 전에 호출되며, 타이머 제거, 네트워크 요청 취소, componentDidMount() 내에서 생성된 데이터 unsubscribing 등 필요한 모든 정리 작업을 수행합니다.
      • 이제 컴포넌트는 다시 렌더링되지 않으므로, 이 메서드 내에서 setState()를 호출하면 안 됩니다.
    • 예시
    import React, { Component } from 'react';
    
    class ExampleComponent extends Component {
      constructor(props) { // 컴포넌트가 생성될 때 호출
        super(props);
        this.state = { count: 0 };  // 초기 상태 설정
        this.handleClick = this.handleClick.bind(this); // 메서드 바인딩
      }
    
      static getDerivedStateFromProps(props, state) { // 컴포넌트의 초기 상태를 설정하거나 프로퍼티에 따라 상태를 업데이트할 필요가 있을 때 호출
        return null;  // 새로운 state 리턴
      }
    
      componentDidMount() { // 컴포넌트가 마운트되고 DOM에 삽입된 후 실행
        // 외부 데이터 불러오기 혹은 이벤트 리스너 등록
      }
    
      shouldComponentUpdate(nextProps, nextState) { // 컴포넌트의 업데이트 여부를 결정
        return nextState.count !== this.state.count; // count 상태가 변경되었을 때만 업데이트가 발생
      }
    
      getSnapshotBeforeUpdate(prevProps, prevState) {
        // render()가 호출된 후, DOM이 업데이트되기 전에 호출될 작업
      }
    
      componentDidUpdate(prevProps, prevState, snapshot) {
        // 컴포넌트의 업데이트가 완료된 후에 호출될 작업
      }
    
      componentWillUnmount() { 
        // 컴포넌트가 DOM에서 제거되기 전의 호출될 작업
        // 이벤트 리스너를 제거 혹은 다른 정리 작업
      }
    
      handleClick() {
        this.setState({ count: this.state.count + 1 });
      }
    
      render() { // UI 업데이트
        console.log('render');
        return (
          <div>
            <h1>{this.props.title}</h1>
            <p>You clicked {this.state.count} times</p>
            <button onClick={this.handleClick}>Click me</button>
          </div>
        );
      }
    }
    
    export default ExampleComponent;

2. 함수형 컴포넌트에서 생명 주기 이벤트 다루기

useEffect()란?

  • useEffect()는 함수형 컴포넌트에서 Side Effect를 처리하기 위한 React Hook입니다.
    • React hook
      • React 버전 16.8부터 추가된 기능으로, 함수형 컴포넌트에서도 상태(state)나 생명주기(lifecycle) 등의 기능을 사용할 수 있도록 해줍니다.
      • 이전에는 클래스형 컴포넌트에서만 사용할 수 있었던 기능들을 함수형 컴포넌트에서도 사용할 수 있게 만들어주는 역할을 합니다.
  • useEffect를 사용하여 Side Effect를 처리할 때, 이벤트 리스너나 타이머 등의 리소스를 사용하고 있었다면, cleanup 함수를 사용하여 이러한 리소스를 해제해 주어야 합니다.
  • useEffect의 기본 문법은 다음과 같습니다.
    useEffect(() => {
      // side effect code
      return () => {
        // cleanup function
      }
    }, dependency list);
  • Side Effect
    • 컴포넌트 외부와 상호 작용하여 발생하는 작업
    • 예시
      • Fetching data from a server
      • Manipulating the DOM
      • Subscribing to events
      • Setting timers
      • Loading and unloading libraries
      • Managing state
  • dependency list
    • useEffect가 실행되는 조건을 설정하는 배열입니다.
    • 변경될 때만 side effect code가 실행됩니다.
    • 빈 배열인 경우, side effect code는 컴포넌트가 마운트될 때만 실행됩니다.
  • cleanup function
    • useEffect가 리턴하는 함수로, useEffect hook이 unmount 되거나, 다음 useEffect 훅이 수행되기 직전에 호출됩니다.
    • Side Effect에서 발생한 리소스를 정리하거나 해제하는 역할을 합니다.

useEffect로 생명 주기 이벤트 다루기

  • useEffect는 마운트, 언마운트, 그리고 업데이트와 같은 생명 주기 이벤트 시점에서도 호출됩니다.
  • useEffect의 콜백 함수는 컴포넌트가 렌더링된 후(마운트 및 업데이트 후) 또는 언마운트 되기 전에 자동으로 비동기적 실행됩니다.
  • 따라서 useEffect를 이용하여 컴포넌트의 생명 주기 이벤트를 다룰 수 있습니다.
  • uesEffect의 생명 주기는 다음과 같습니다.
    1. 컴포넌트 렌더링 시, useEffect 콜백 함수 실행
    2. useEffect 콜백 함수가 cleanup 함수를 리턴
    3. 컴포넌트 업데이트 시, 이전에 리턴된 cleanup 함수 실행 및 새로운 Effect 콜백 함수 실행
    4. 컴포넌트 unmount 시, 마지막으로 리턴된 cleanup 함수 실행

컴포넌트의 생명 주기와 다른 점

  • 컴포넌트의 생명 주기는 마운트, 업데이트, 언마운트되는 시점에 각각 실행되는 작업들을 처리하지만, useEffect()의 생명 주기는 useEffect() 콜백 함수가 실행될 때 작업들을 처리합니다.
  • 이펙트의 생명 주기는 컴포넌트가 마운트, 업데이트, 언마운트될 때 뿐만 아니라 dependency array의 내용이 변경될 때마다 발생할 수 있습니다.
  • 이렇게 발생하는 생명 주기의 변화를 관리하기 위해 React는 Effect의 의존성이 올바르게 지정되어 있는지를 검사하는 linter 규칙을 제공합니다. 이를 통해 Effect가 항상 최신의 props, satate와 동기화되도록 유지할 수 있습니다.
  • useEffect()를 사용할 때는 컴포넌트의 관점(마운트, 업데이트 또는 마운트 해제 방법)이 아닌 각 개별 효과의 관점(동기화 시작 및 중지 방법)에서 생각해야합니다.

useEffect의 장점

  • 컴포넌트 생명 주기와 분리: useEffect를 사용하면 컴포넌트의 생명 주기와 상관없이 비동기 작업이나 이벤트 핸들러 등의 동작을 처리할 수 있습니다. 이는 컴포넌트의 코드를 더욱 깔끔하게 유지할 수 있고, 코드 재사용성도 높여줍니다.
  • 의존성 배열(dependency array): useEffect를 사용하면 의존성 배열(dependency array)을 이용하여 특정 값이 변경될 때만 useEffect 콜백 함수가 실행되도록 할 수 있습니다. 이를 이용하면 불필요한 렌더링을 방지할 수 있습니다.
  • Cleanup 함수: useEffect를 사용하면 클린업(Cleanup) 함수를 제공할 수 있습니다. 이 함수를 이용하면 컴포넌트가 언마운트될 때, 혹은 의존성 배열 내의 값이 변경되어 새로운 useEffect 콜백 함수가 실행될 때 이전 useEffect 콜백 함수에서 생성된 리소스를 정리할 수 있습니다.
  • 다수의 효과(Effects) 사용 가능: 컴포넌트 내에서 useEffect를 여러번 사용할 수 있습니다. 이를 이용하면 각각의 효과에 대해 따로 의존성 배열, 클린업 함수 등을 설정하여 코드를 더욱 유연하고 효과적으로 관리할 수 있습니다.
  • 따라서, useEffect를 이용하면 컴포넌트 코드를 더욱 유연하게 구성할 수 있고, 코드 재사용성도 높일 수 있습니다. 또한, 의존성 배열과 클린업 함수를 이용하여 특정 값의 변경에 대응하거나, 리소스를 정리하는 등의 작업을 보다 효과적으로 처리할 수 있습니다.

Reference

profile
job's done

0개의 댓글