코딩/리액트

[새싹 성동 2기] React 컴포넌트 라이프사이클과 메서드 활용하기

insu90 2024. 11. 19. 18:56

React에서 컴포넌트는 생성, 업데이트, 소멸이라는 세 가지 주요 라이프사이클 단계가 있습니다. 각 단계마다 호출되는 특정 메서드가 있으며, 이를 적절히 활용하면 컴포넌트의 동작을 보다 세밀하게 제어할 수 있습니다.

이번 포스트에서는 React 클래스형 컴포넌트에서 라이프사이클 메서드를 어떻게 사용하고, 이를 통해 부모 컴포넌트로부터 전달된 데이터를 자식 컴포넌트가 어떻게 처리하는지 살펴보겠습니다.

1. componentDidMount 메서드

componentDidMount는 컴포넌트가 처음 렌더링된 후 한 번 호출됩니다. 이 메서드는 주로 API 요청이나 비동기 작업을 처리하는 데 유용하게 사용됩니다.

예제: 부모 컴포넌트로부터 전달된 글자색을 자식 컴포넌트에서 반영하기

  1. LifecycleSample.js (자식 컴포넌트)
    import { Component } from "react";
    
    class LifecycleSample extends Component {
        state = {
            count: 0
        };
    
        handleCount = () => {
            console.log("하나 증가 버튼을 클릭");
            this.setState({ count: this.state.count + 1 });
        };
    
        render() {
            return (
                <>
                    <h1>자식 컴포넌트</h1>
                    <h1 style={{ color: this.props.color }}>
                        {this.state.count}
                    </h1>
                    <button onClick={this.handleCount}>하나 증가</button>
                </>
            );
        }
    }
    
    export default LifecycleSample;
     
  2.  App.js (부모 컴포넌트)
    import { useState } from "react";
    import LifecycleSample from "./LifecycleSample";
    
    // 랜덤 컬러를 생성하는 함수를 정의
    const getRandomColor = () => '#' + Math.floor(Math.random() * 16777215).toString(16);
    
    function App() {
      const [color, setColor] = useState('#000000');
    
      const changeColor = () => {
        console.log("랜덤 컬러 생성 버튼을 클릭했습니다.");
        setColor(getRandomColor());
      };
    
      return (
        <>
          <LifecycleSample color={color} />
          <button onClick={changeColor}>랜덤 컬러 생성</button>
        </>
      );
    }
    
    export default App;

위 코드에서는 부모 컴포넌트 App에서 버튼을 클릭하여 랜덤한 색을 생성하고, 이를 자식 컴포넌트 LifecycleSample에 전달하여 그 색을 반영합니다.

2. 컴포넌트 생성과 업데이트, 소멸에 따른 로그 확인

React 클래스형 컴포넌트는 라이프사이클 메서드를 활용하여 컴포넌트의 생성, 업데이트, 소멸 과정을 추적할 수 있습니다. 이를 통해 컴포넌트의 상태 변화에 대한 이해를 높일 수 있습니다.

예제: 라이프사이클 메서드를 통한 로그 확인

  1. LifecycleSample.js (자식 컴포넌트)
    import { Component } from "react";
    
    class LifecycleSample extends Component {
        state = {
            count: 0,
            color: this.props.color
        };
    
        handleCount = () => {
            console.log("하나 증가 버튼을 클릭");
            this.setState({ count: this.state.count + 1 });
        };
    
        constructor(props) {
            super(props);
            console.log("constructor is called");
        }
    
        componentDidMount() {
            console.log("componentDidMount is called");
        }
    
        componentDidUpdate() {
            console.log("componentDidUpdate is called");
        }
    
        componentWillUnmount() {
            console.log("componentWillUnmount is called");
        }
    
        render() {
            console.log("render is called");
            return (
                <>
                    <h1>자식 컴포넌트</h1>
                    <h1 style={{ color: this.props.color }}>
                        {this.state.count}
                    </h1>
                    <button onClick={this.handleCount}>하나 증가</button>
                </>
            );
        }
    }
    
    export default LifecycleSample;
  2. App.js (부모 컴포넌트)
    import { useState } from "react";
    import LifecycleSample from "./LifecycleSample";
    
    // 랜덤 컬러를 생성하는 함수를 정의
    const getRandomColor = () => '#' + Math.floor(Math.random() * 16777215).toString(16);
    
    function App() {
      const [color, setColor] = useState('#000000');
      const [isVisible, setIsVisible] = useState(false);
    
      const changeColor = () => {
        console.log("랜덤 컬러 생성 버튼을 클릭했습니다.");
        setColor(getRandomColor());
      };
    
      const changeIsVisible = () => {
        console.log(`자식 컴포넌트 ${isVisible ? '숨기기' : '보이기'} 버튼 클릭했습니다.`);
        setIsVisible(!isVisible);
      };
    
      return (
        <>
          <button onClick={changeIsVisible}>자식 컴포넌트 {isVisible ? '숨기기' : '보이기'}</button>
          {
            isVisible &&
            <div>
              <LifecycleSample color={color} />
              <button onClick={changeColor}>랜덤 컬러 생성</button>
            </div>
          }
        </>
      );
    }
    
    export default App;

위 코드를 실행하면 각 버튼 클릭에 따라 컴포넌트가 생성되고, 상태 업데이트나 소멸 시점에 따라 라이프사이클 메서드가 호출되어 로그를 출력합니다.

 

3. getDerivedStateFromProps와 상태 동기화

부모 컴포넌트에서 전달된 데이터가 변경될 때, 자식 컴포넌트의 상태를 동기화하기 위해 getDerivedStateFromProps 메서드를 사용할 수 있습니다.

예제: 부모의 글자색을 자식 컴포넌트의 상태로 동기화하기

import { Component } from "react";

class LifecycleSample extends Component {
    state = {
        count: 0,
        color: this.props.color
    };

    handleCount = () => {
        console.log("하나 증가 버튼을 클릭");
        this.setState({ count: this.state.count + 1 });
    };

    static getDerivedStateFromProps(props, state) {
        console.log("getDerivedStateFromProps is called");
        if (state.color !== props.color) {
            return { color: props.color };
        }
        return null;
    }

    render() {
        console.log("render is called");
        return (
            <>
                <h1>자식 컴포넌트</h1>
                <h1 style={{ color: this.props.color }}>
                    {this.state.count}
                </h1>
                <h2>color: {this.state.color}</h2>
                <button onClick={this.handleCount}>하나 증가</button>
            </>
        );
    }
}

export default LifecycleSample;

위 코드에서 getDerivedStateFromProps는 부모 컴포넌트로부터 전달된 color가 자식 컴포넌트의 상태와 일치하지 않을 때만 상태를 업데이트하도록 처리합니다.

 

4. shouldComponentUpdate를 사용한 조건부 렌더링

shouldComponentUpdate 메서드를 사용하여 컴포넌트의 렌더링을 조건부로 제어할 수 있습니다. 예를 들어, 카운터가 3의 배수일 때는 렌더링을 하지 않도록 설정할 수 있습니다.

shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate is called");
    return nextState.count % 3 !== 0; // 카운터가 3의 배수일 때는 렌더링을 하지 않음
}

 

5. getSnapshotBeforeUpdate 메서드를 통한 렌더링 직전 데이터 캡처

getSnapshotBeforeUpdate는 렌더링 직전에 호출되어 이전 props와 state를 비교하여 특정 데이터를 캡처할 수 있습니다. 이 데이터는 componentDidUpdate에서 활용될 수 있습니다.

getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log("getSnapshotBeforeUpdate is called");
    return prevProps.color;
}

componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("componentDidUpdate is called");
    if (snapshot) {
        console.log(`업데이트 직전의 글자색: ${snapshot}`);
    }
}

 

React 클래스형 컴포넌트의 라이프사이클 메서드를 활용하면 컴포넌트의 상태나 props가 변경될 때 어떻게 반응할지 세밀하게 제어할 수 있습니다. 각 메서드의 호출 시점에 대한 이해는 특히 비동기 작업이나 상태 동기화, 렌더링 성능 최적화에서 매우 유용하게 사용됩니다.

 

 

*생성형 AI 활용한 클라우드&보안 전문가 양성캠프 과정의 교육내용 정리 자료입니다.