Learning React(6. React 컴포넌트 생명주기)

min seung moon·2021년 8월 5일
0

Learning React

목록 보기
6/15
post-thumbnail

1. 컴포넌트 생명주기

01. 생명주기 메소드

  • 전부가 생명주기 메소드는 아니지만 생명주기 메소드와 함께 자주 사용된다
    • 추가로 render 메소드
  • componentWillMount
  • componentDidMount
  • componentWillUnmount
  • componentWillUpdate
  • componentDidUpdate
  • shouldComponentUpdate
  • componentDidCatch

02. 생명주기 메소드의 작동 확인

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>Lifecycle Methods</title>
  <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  <style>
    #container {
      padding: 50px;
      background-color: #FFF;
    }
  </style>
</head>

<body>
  <div id="container"></div>
  <script type="text/babel">
    var destination = document.querySelector("#container");

    class Counter extends React.Component {
        render() {
            var textStyle = {
                fontSize: 72,
                fontFamily: "sans-serif",
                color: "#333",
                fontWeight: "bold"
            };

            return (
                <div style={textStyle}>
                    {this.props.display}
                </div>
            );
        }
    }

    class CounterParent extends React.Component {
        constructor(props, context) {
            super(props, context);

            console.log("constructor: Default state time!");

            this.state = {
                count: 0
            };

            this.increase = this.increase.bind(this);
        }

        increase() {
            this.setState({
                count: this.state.count + 1
            });
        }
        
        render() {
            var backgroundStyle = {
                padding: 50,
                border: "#333 2px dotted",
                width: 250,
                height: 100,
                borderRadius: 10,
                textAlign: "center"
            };

            return (
                <div style={backgroundStyle}>
                    <Counter display={this.state.count} />
                    <button onClick={this.increase}>
                        +
                    </button>
                </div>
            );
        }
    };

    ReactDOM.render(
        <div>
            <CounterParent />
        </div>,
        destination
    );
</script>
</body>

</html>

  • 라이프사이클 메소드 적용
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>Lifecycle Methods</title>
  <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  <style>
    #container {
      padding: 50px;
      background-color: #FFF;
    }
  </style>
</head>

<body>
  <div id="container"></div>
  <script type="text/babel">
    var destination = document.querySelector("#container");

    class Counter extends React.Component {
        render() {
            var textStyle = {
                fontSize: 72,
                fontFamily: "sans-serif",
                color: "#333",
                fontWeight: "bold"
            };

            return (
                <div style={textStyle}>
                    {this.props.display}
                </div>
            );
        }
    }

    class CounterParent extends React.Component {
        constructor(props, context) {
            super(props, context);

            console.log("constructor: Default state time!");

            this.state = {
                count: 0
            };

            this.increase = this.increase.bind(this);
        }

        increase() {
            this.setState({
                count: this.state.count + 1
            });
        }

        componentWillUpdate(newProps, newState) {
            console.log("componentWillUpdate: Component is about to update!");
        }

        componentDidUpdate(prevProps, prevState) {
            console.log("componentDidUpdate: Component just updated!");
        }

        componentWillMount() {
            console.log("componentWillMount: Component is about to mount!");
        }

        componentDidMount() {
            console.log("componentDidMount: Component just mounted!");
        }

        componentWillUnmount() {
            console.log("componentWillUnmount: Component is about to be removed from the DOM!");
        }

        shouldComponentUpdate(newProps, newState) {
            console.log("shouldComponentUpdate: Should component update?");

            if (newState.count < 5) {
                console.log("shouldComponentUpdate: Component should update!");
                return true;
            } else {
                ReactDOM.unmountComponentAtNode(destination);
                console.log("shouldComponentUpdate: Component should not update!");
                return false;
            }
        }

        componentWillReceiveProps(newProps) {
            console.log("componentWillReceiveProps: Component will get new props!");
        }

        render() {
            var backgroundStyle = {
                padding: 50,
                border: "#333 2px dotted",
                width: 250,
                height: 100,
                borderRadius: 10,
                textAlign: "center"
            };

            return (
                <div style={backgroundStyle}>
                    <Counter display={this.state.count} />
                    <button onClick={this.increase}>
                        +
                    </button>
                </div>
            );
        }
    };

    console.log("defaultProps: Default prop time!");
    CounterParent.defaultProps = {

    };

    ReactDOM.render(
        <div>
            <CounterParent />
        </div>,
        destination
    );
</script>
</body>

</html>



03. 초기 렌더링 단계

-1. 기본 속성 설정

  • 컴포넌트의 defaultProps 속성은 this.props의 기본값을 지정할 수 있게 해준다
  • CounterParent 컴포넌트의 name속성을 설정해보자
    • 이 속성은 컴포넌트가 생성되기 전이나 부모로부터 속성이 전달될 때 실행된다
CounterParent.defaultProps = {
      name : "Iron Man"
};


-2. 기본 상태 설정

  • 이 단계는 컴포넌트의 생성자 안에서 진행된다 따라서 컴포넌트 생성 과정에서 this.state의 기본값을 지정할 수 있는 기회로 삼을 수 있다

-3. ComponentWillMount

  • 컴포넌트가 DOM 안으로 렌더링되기 전에 호출되는 마지막 메소드
  • 중요한 점은 이 메소드 안에서는 setState를 호출해도 컴포넌트가 다시 렌더링 되지 않는다는 점

-4. render

  • 모든 컴포넌트에 정의돼 있어야 하는 메소드이며, JSX를 리턴하는 책임을 진다
  • 렌더링이 필요 없다면 단순히 null이나 false를 리턴하면 된다

-5. componentDidMount

  • 컴포넌트가 렌더링돼 DOM에 자리 잡은 직후 호출된다
  • 이 시점에서는 컴포넌트 생성이 완료됐는지 여부를 걱정할 필요 없이, 안심하고 DOM 쿼리 작업을 수행할 수 있다
  • 모든 준비를 마친 컴포넌트에만 의존하는 코드는 모두 이곳에 지정하면 된다
  • render 제외 1 ~ 5까지는 한번만 실행 된다

04. 업데이트 단계

  • 컴포넌트가 DOM 안으로 추가되면, 이후에 속성이나 상대가 변경될 때 업데이트되며 다시 렌더링 된다 이전까지의 가장 큰 차이점은 이 과정에서 다른 생며주기 메소드들이 호출 된다

-1. 상태 변경 다루기

  • 상태가 변경되면 컴포넌트는 render 메소드를 재호출 한다
  • 그 결과에 의존하는 다른 모든 컴포넌트 역시 자신들의 render 메소드를 호출하며 이는 화면에 보이는 컴포넌트가 항상 최신 버전을 보장하게 된다

-2. ShouldComponentUpdate

  • 때로 상태가 변경이 돼어도 컴포넌트의 업데이트를 바라지 않을 수 있다 그 때 이 메소드는 업데이트 여부를 제어할 수 있게 해준다
  • 만약 true를 리턴하면 컴포넌트는 업데이트 되고, false를 리턴하면 업데이트를 건너뛰게 된다
  • 아래 메소드는 newProps와 newState 두 인자를 받는다
  • 여기서 상태 속성인 count 값이 5보다 작으면 true를 return하여 컴포넌트 업데이트를 진행하고 아니면 flase를 리턴하여 업데이트를 안한다

-3. componentWillUpdate

  • 컴포넌트가 업데이트 되기 직전에 호출된다
  • 이 메소드 안에서는 this.setState를 사용해 상태를 변경할 수는 없다!

-4. render

  • shouldComponentUpdate가 false를 리턴함으로써 업데이트 작업을 건너뛰지만 않는다면, render 메소드가 재호출됨으로써 컴포넌트가 올바르게 보이게 보장한다

-5. componentDidUpdate

  • 이 메소드는 컴포넌트가 업데이트되고 render 메소드의 실행이 끝난 후에 호출된다
  • 업데이트 후에 수행하고 싶은 코드가 있다면 이 메소드가 가장 알맞은 장소다

-6. 속성 변경 다루기

  • 컴포넌트가 업데이되는 또 다른 경우는 DOM안으로 렌더링 된 후에 속성 값이 변경될 때다

-7. componentWillReceiveProps

  • 이 메소드는 하나의 인자를 받는데 그 인자에는 새로 할당하고자 하는 속성 값이 포함된다
  • 그 외에 생명주기 메소드는 위에 다시 확인하면 된다!

05. 언마운트 단계

  • 컴포넌트가 소멸되고 DOM에서 제거되는 언마운트 단계

-1. componentWillUnmount

  • 언마운트 단계에서 유일하게 호출되는 생명주기 메서드다
  • 이 메서드에서 이벤트 리스너를 제거하거나 타이머를 중단시키는 등의 뒷정리를 할 수 있다
  • 이 메서드가 실행된 후에 컴포넌트는 실제로 DOM으로 부터 제거된다

profile
아직까지는 코린이!

0개의 댓글

관련 채용 정보