React & React Native/이해하기

[React] 함수형 컴포넌트 생명주기(lifecycle) 이해하기

adjh54 2022. 6. 12. 17:41
반응형
해당 글은 React의 ‘함수형 컴포넌트’의 ‘생명주기’를 이해하기 위한 글입니다.

 

 

💡 [참고] 이전에 작성한 ‘클래스 컴포넌트의 생명주기'를 이해하고 오시면 더 쉽게 이해가 가능합니다
 

[React] 클래스 컴포넌트 생명주기(lifecycle)

해당 글은 React의 '클래스형 컴포넌트'의 '생명주기(lifecycle)'를 이해하기 위한 글입니다. 1) React의 생명주기 용어 용어 설명 ~ will 어떤 작업을 수행하기 전에 실행되는 메서드와 관련된 용어입니

adjh54.tistory.com

 

 

 

1) 함수형 컴포넌트 생명주기


💡 함수형 컴포넌트는 React Hook 이라고도 하며 React 16.8 버전 이후부터 React 요소로 추가가 되었으며, 해당 글에서는 React 17 이상 버전을 기준으로 작성하였습니다.

[출처] https://wavez.github.io/react-hooks-lifecycle/

 

💡 해당 함수형 컴포넌트에서는 이전 클래스 컴포넌트와 비교하여 설명하자면 클래스형 컴포넌트의 라이프사이클 메서드로 사용되었던 constructor(), render(), ComponenDidMount(), componentDidUpdate(), componentWillUnmount()는 함수형 컴포넌트에서 아래와 같이 사용을 하고 있습니다.

 

[참고] 클래스형 컴포넌트와 함수형 컴포넌트의 비교
분류 클래스형 컴포넌트 함수형 컴포넌트
Mounting constructor() 함수형 컴포넌트 내부
Mounting render() return()
Mounting ComponenDidMount() useEffect()
Updating componentDidUpdate() useEffect()
UnMounting componentWillUnmount() useEffect()
💡 생명주기 순서 요약 

1. 컴포넌트가 호출되어 로드됩니다.

2. 컴포넌트 내부 함수 수행 
- 데이터의 초기화를 수행합니다.

3. return() 함수 실행
- 화면의 렌더링을 수행합니다

4. useEffect() 실행

💡 조건부 수행

5-1. useEffect() 실행 
- 컴포넌트의 '변화'가 발생하는 경우 수행합니다.

5-2. useEffect() 실행 
- 컴포넌트의 '소멸'이 발생하는 경우 수행합니다.

 

 [더 알아보기]

💡 렌더링(Rendering) 이란?

- React 내에서는 컴포넌트 렌더링이라고도 하며, 컴포넌트 내에 엘리먼트 요소들(HTML, React 사용자 정의 태그)을 화면상에 그리는 동작을 의미한다.

💡 리 렌더링(re-Rendering) 이란?

 - 컴포넌트 내에 엘리먼트 요소들을 코드를 기반으로 화면의 그리는 작업을 다시 수행하는 것을 의미한다.
 

엘리먼트 렌더링 – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

 

2) React의 생명주기 상세 설명


1. [Mounting] 컴포넌트 내부

💡컴포넌트 내부 

- 컴포넌트가 호출이 되었을 때 가장 먼저 호출이 되는 것은 컴포넌트 내부입니다.


- 라이프 사이클 메서드라고 할 수는 없지만 클래스 컴포넌트의 constructor()를 이해하기 위해 설명합니다.
- 동일하게 State를 정의하거나 사용될 함수들에 대해서 미리 정의를 하는 공간입니다.

 

[참고] 해당 메서드 사용 예시
/**
 * 함수형 컴포넌트 예시 
 */
const LifecycleFunctionComponent: React.FC = (props: any) => {

    /**
     * 컴포넌트 호출 시 가장 먼저 호출이 되는 공간
     * 컴포넌트에서 사용 될 state나 함수들을 정의 하는 공간입니다.
     */
    console.log("해당 부분이 제일 먼저 호출이 됩니다.");

    const [userInfo, setUserInfo] = useState<any>({
        userId: 'adjh54',
        userAge: 50,
        isShowTempComponent: false,
    });

    return (
        <></>
    )

};
export default LifecycleFunctionComponent;

 

2. [Mounting] return()

 💡return()

- 미리 구현된 HTML을 화면상에 그려지는 과정(렌더링)을 수행하는 함수를 의미합니다.

- 해당 메서드 안에서는 부모 컴포넌트로 전달받은 'props' 값의 접근이 가능합니다.
 - 컴포넌트 내부에서 정의한 'state' 값의 접근이 가능합니다.

 

[참고] 해당 메서드 사용 예시
import React, { useEffect, useState } from "react";

/**
 * 함수형 컴포넌트 예시 
 */
const LifecycleFunctionComponent: React.FC = (props: any) => {

    const [userInfo, setUserInfo] = useState<any>({
        userId: 'adjh54',
        userAge: 50,
        isShowTempComponent: false,
    });

    /**
     * 미리 구현한 HTML를 화면상에 보여주는 메서드이다.
     */
    return (
        <>
            {console.log("Renering ...")}
            <div>
                <h1>Main Function Component 입니다.</h1>
                <div>{userInfo.userAge}</div>
            </div>
        </>
    );

};
export default LifecycleFunctionComponent;

 

 

3. [Mounting/Updating/Unmounting] useEffect()

💡useEffect()

- 해당 메서드를 통하여서 Mounting/Updating/Unmounting 처리가 가능합니다.

- useEffect()는 한개 또는 여러개 선언이 가능합니다.

💡 [ 메서드 구조 ]
useEffect( function, deps? );

* function : useEffect가 수행될 때 실행되는 함수
* deps [optional] : 배열 형태이며, 의존(dependency) 값을 의미한다.

 

💡[더 알아가기] deps [optinal] 값의 의미
deps의 값 구조 설명
값이 없을 경우 useEffect(()⇒{}) 화면이 렌더링 된 이후 수행이 되며, 리 렌더링이 발생하는 경우 다시 수행이 된다
빈 배열 인경우 useEffect(()⇒{}, []) 화면이 렌더링 된 이후에만 수행이 된다.
배열 값이 존재하는 경우 useEffect(()⇒{}, [값]) 화면이 렌더링 된 이후에 수행이 되고, ‘값’이 변경되었을 경우 해당 메서드가 수행이 된다.

 

3.1. [Mounting] useEffect()

💡useEffect(()⇒{}, [])

- 컴포넌트 내에서 렌더링이 수행된 이후에 단 한번만 실행이 되는 메서드이다.


- deps 파라미터를 빈 배열로 수행하면 렌더링이 수행된 이후 최초 한번 수행이 된다.

 

[참고] 해당 메서드 사용 예시
import React, { useEffect, useState } from "react";
import { LifecycleType } from "./LifecycleType";

/**
 * 함수형 컴포넌트 예시 
 */
const LifecycleFunctionComponent: React.FC = (props: any) => {

    /**
     * 1. 컴포넌트 호출 시 가장 먼저 호출이 되는 공간
     * 컴포넌트에서 사용 될 state나 함수들을 정의 하는 공간입니다.
     */
    console.log("해당 부분이 제일 먼저 호출이 됩니다.");

    const [userInfo, setUserInfo] = useState<LifecycleType>({
        userId: 'adjh54',
        userAge: 50,
        isShowTempComponent: false,
    });

    /**
     * 3. 컴포넌트 내에서 렌더링이 수행된 이후에 실행이 되는 메서드이다.
     * @returns {void}
     */
    useEffect(() => {
        console.log("화면이 렌더링 된 이후에 바로 수행이 됨: componentDidMount()과 동일");
    }, []);

    /**
     * 2. 미리 구현한 HTML(JSX)를 화면상에 보여주는 메서드이다.
     */
    return (
        <>
            {console.log("Renering ...")}
            <div>

                <h1>Main Function Component 입니다.</h1>
                <div>{userInfo.userAge}</div>
            </div>
        </>
    );
};
export default LifecycleFunctionComponent;

 

3.2. [Updating] useEffect()

💡 useEffect(()⇒{}, [값])

-  컴포넌트 내에서 '변화'가 발생된 이후 호출되는 메서드를 의미합니다.

- 변화라 함은 부모 컴포넌트로부터 전달받은 props 값의 변화가 발생하거나 부모 컴포넌트가 리 렌더링이 발생을 하는 경우 수행됩니다.
- 해당 컴포넌트 내에서 state의 값이 변하는 경우 수행됩니다.

 

[참고] 해당 메서드 사용 예시
💡 하단의 예시에서는 props.appState, userInfo.userAge 값의 변화가 생겼을 경우, useEffect() 함수를 재 실행하도록 처리가 되어 있다.
import React, { useEffect, useState } from "react";
import { LifecycleType } from "./LifecycleType";

/**
 * 함수형 컴포넌트 예시 
 */
const LifecycleFunctionComponent: React.FC = (props: any) => {

    /**
     * 컴포넌트 호출 시 가장 먼저 호출이 되는 공간
     * 컴포넌트에서 사용 될 state나 함수들을 정의 하는 공간입니다.
     */
    console.log("해당 부분이 제일 먼저 호출이 됩니다.");

    const [userInfo, setUserInfo] = useState<LifecycleType>({
        userId: 'adjh54',
        userAge: 50,
        isShowTempComponent: false,
    });

    /**
     * 컴포넌트 내에서 변화가 발생하였을 경우에 실행되는 메서드이다.
     */
    useEffect(() => {
        console.log("전달 받은 props의 값에 변화가 생겼을 경우 / 사용자 나이의 변화가 발생하였을 경우 수행이 된다. : componentDidUpdate()와 동일");
    }, [props.appState, userInfo.userAge]);

    /**
     * 미리 구현한 HTML(JSX)를 화면상에 보여주는 메서드이다.
     */
    return (
        <>
            {console.log("Renering ...")}
            <div>

                <h1>Main Function Component 입니다.</h1>
                <div>{userInfo.userAge}</div>
            </div>
        </>
    );

};
export default LifecycleFunctionComponent;

 

 

3.3. [Unmounting] useEffect()

💡useEffect(()⇒{ return { // }}, [값])

- 컴포넌트가 DOM에서 제거되기 직전에 호출되는 메서드입니다.

- 컴포넌트의 DOM이 제거될 때 수행이 됩니다. 예를 들어 A라는 컴포넌트 내에서 B라는 컴포넌트를 부르고 있을 전제라고 할 때, B 컴포넌트를 조건부에 따라서 소멸을 시킬 경우 해당 라이프사이클 메서드가 수행이 됩니다.

 

[참고] 해당 메서드 사용 예시
💡 LifeCycleFunctionComponent이라는 컴포넌트에서 LifeCycleUnmountComponent라는 컴포넌트를 화면상에 보여주고 있습니다. 버튼을 눌렀을 경우 해당 컴포넌트가 제외될 때, LifeCycleUnmountComponent 컴포넌트의 'useEffect()'가 수행되는 것을 확인할 수 있습니다.
import React, { useEffect, useState } from "react";
import { LifecycleType } from "../../type/lifecycle/LifecycleType";

/**
 * 함수형 컴포넌트 예시 
 */
const LifeCycleFunctionComponent: React.FC = (props: any) => {

    const [isShowTempComp, setIsSHowTempComp] = useState<boolean>(true);

    /**
     * 컴포넌트 호출 시 가장 먼저 호출이 되는 공간
     * 컴포넌트에서 사용 될 state나 함수들을 정의 하는 공간입니다.
     */
    console.log("해당 부분이 제일 먼저 호출이 됩니다.");

    const [userInfo, setUserInfo] = useState<LifecycleType>({
        userId: 'adjh54',
        userAge: 50,
        isShowTempComponent: false,
    });

    /**
     * 임시 컴포넌트 Unmount
     */
    const fn_unmountCompoent = () => {
        setIsSHowTempComp(!isShowTempComp);
    }

    /**
     * 미리 구현한 HTML(JSX)를 화면상에 보여주는 메서드이다.
     */
    return (
        <>
            {console.log("Renering ...")}
            <div>
                <h1>Main Function Component 입니다.</h1>
                <button onClick={fn_unmountCompoent}>컴포넌트 제거</button>
                {
                    isShowTempComp && (
                        <LifeCycleUnmountComponent />
                    )
                }
            </div>
        </>
    );
};
export default LifeCycleFunctionComponent;

const LifeCycleUnmountComponent = () => {

    useEffect(() => {
        return () => {
            console.log("LifeCycleUnmountComponent가 Unmount 되었습니다.")
        }
    }, []);

    return (
        <div>
            <h1> Unmount Component</h1>
        </div>
    )

}

 

 

 

오늘도 감사합니다. 😀

 

반응형