React[Component] - Lifecycle(1)

일상 코딩·2022년 5월 7일
0

React

목록 보기
10/45
post-thumbnail
post-custom-banner

01.Component Lifecycle (Version 16.3 이전)

  • 리액트 컴포넌트는 탄생부터 죽음까지 여러 지점에서 개발자가 작업이 가능하도록 메소드를 오버라이딩할 수 있게 해줍니다.
  • 해당 내용은 16.3 버전 이전의 내용을 다루고 있습니다.
  • 탄생: Initialization, Miunting
  • 죽음: Unmounting

02.Component Declarative

  • Initialization: constructor가 불리면서 props세팅 및 state의 초기값이 설정된다.
  • Mounting: render가 실행 되면서 화면에 최초로 그려진다.
  • updation: Component들은 propsstate가 변경이 되면 update가 진행이 되며 다시 rendering 된다.
  • Unmouting: 해당하는 ComponentDOM상에서 제거가 될 때 실행되는 lifeCycle이다.

1.Mounting

  • 컴포넌트가 처음 실행될 때 Mount라고 표현합니다.
  • 컴포넌트가 시작되면 우선 context, defaultPropsstate를 저장합니다.
  • 그 후에 componentWillMount 메소드를 호출합니다.
  • 그리고 render로 컴포넌트를 DOM에 부착한 후 Mount가 완료된 후 componentDidMount가 호출됩니다.

실행 순서

  • state, context, defaultProps 저장
  • componentWillMount
  • render
  • componentDidMount

2.Updation
2-1.Props Update

  • 업데이트가 발생하였음을 감지하고 componentWillReceiveProps 메소드가 호출됩니다.
  • 그 후 shouldComponentUpdate, componentWillUpdate가 차례대로 호출된 후 업데이트가 완료(render)되면 componentDidUpdate가 됩니다.
  • 이 메소드들은 첫 번째 인자로 바뀔 props에 대한 정보를 가지고 있습니다.

실행 순서

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

2-2.State Update

  • props update와 과정이 같지만 componentWillReceiveProps 메소드는 호출되지 않습니다.
  • 메소드의 두 번째 인자로는 바뀔 state에 대한 정보를 가지고 있습니다.
  • componentDidUpdate는 두 번째 인자로 바뀌기 이전의 state에 대한 정보를 가지고 있습니다.
  • componentDidMount: update 가 이루어지고 render가 완료된 직후 실행되는 메소드이이며 최초 마운트 될 때는 실행되지 않습니다.

실행 순서

  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

shouldcomponentUpdate

  • Componentupdate 되어야 하는지 말아야하는지를 결정하는 구간 입니다.
  • shouldcomponentUpdate에서는 Boolean 형태의 데이터 값을 반환하며 아직 render하기 전이기 때문에 return값으로 false를 하면 render을 취소할 수 있습니다.
  • 쓸데없는 update가 일어나면 여기서 걸러냅니다.
  • 불필요한 render를 방지하기 위해 주로 사용되며 React component의 성능 최적화여 중요할 역할을 한다.

3.Unmount

  • 컴포넌트가 제거되는 것은 Unmount라고 표현합니다.
  • componentWillUnmount는 더는 컴포넌트를 사용하지 않을 때 발생하는 이벤트 입니다.
  • 이미 제거된 컴포넌트에서 이벤트를 발생시킬 수 없기때문에 componentDidUnmount는 존재하지 않습니다.
  • componentWillMount에서 주로 연결했던 이벤트 리스너를 제거하는 등의 여러 가지 정리 활동을 합니다.

실행 순서

  • componentWillUnmount

03.Component Initialization & Mounting (생성 및 마운트)

  • constructor
  • componentWillMount
  • render(최초 렌더)
  • componentDidMount
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Example</title>

  <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>  
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

<body>
  <div id="root"></div>
	<script type="text/babel">
   
class App extends React.Component {
  state = {
    age: 24,
  }
  constructor(props) {
    super(props)

    console.log("constructor", props)
  }
  render() {
    console.log("render")
    return (
      <div>
        <h2>
          Hello {this.props.name} - {this.state.age}
        </h2>
      </div>
    )
  }

  componentWillMount() {
    console.log("componentWillMount")
  }

  componentDidMount() {
    console.log("componentDidMount")
  }
}

ReactDOM.render(<App name="Mark" />, document.querySelector("#root"))
  </script>	
	</body>
</html>                    

실행 결과

  • $ npx serve
  • 이처럼 Component 생성과 마운트에 대해 알아볼 수 있습니다.
  • 화면의 콘솔창을 보시면 constructor(생성자), componentWillMount, render, componentDidMount 순서로 라이프사이클이 출력되는 것을 볼 수 있습니다.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Example</title>

  <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>  
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

<body>
  <div id="root"></div>
	<script type="text/babel">
   
class App extends React.Component {
  state = {
    age: 24,
  }
  constructor(props) {
    super(props)

    console.log("constructor", props)
  }
  render() {
    console.log("render")
    return (
      <div>
        <h2>
          Hello {this.props.name} - {this.state.age}
        </h2>
      </div>
    )
  }

  componentWillMount() {
    console.log("componentWillMount")
  }

  componentDidMount() {
    console.log("componentDidMount")

    setInterval(() => {
      this.setState(state => ({...state, age: state.age + 1}))
    }, 1000);
  }
}

ReactDOM.render(<App name="Mark" />, document.querySelector("#root"))
  </script>	
	</body>
</html>                    
  • state값을 변경하면 다시 새로 render 됩니다.
  • setInterval 메소드를 사용하면 1초 마다 계속 state.age 값을 1씩 증가시켜 새로 render되게 해줄 수 있습니다.

실행 결과

  • $ npx serve

04.Component Updation (props & state 변경)

  • componentWillReceiveProps (state 변경 시, 실행되지 않음)
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Example</title>

  <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>  
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

<body>
  <div id="root"></div>
	<script type="text/babel">
   
class App extends React.Component {
  state = {
    age: 24,
  }
  constructor(props) {
    super(props)

    console.log("constructor", props)
  }
  render() {
    console.log("render")
    return (
      <div>
        <h2>
          Hello {this.props.name} - {this.state.age}
        </h2>
      </div>
    )
  }

  componentWillMount() {
    console.log("componentWillMount")
  }

  componentDidMount() {
    console.log("componentDidMount")

    setInterval(() => {
      this.setState(state => ({...state, age: state.age + 1}))
    }, 1000);
  }

  componentWillReceiveProps(nextProps) {
    console.log("componentWillReceiveProps", nextProps);
  }

  shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate", nextProps), nextState;

    return true;
  }

  componentWillUpdate(nextProps, nextState) {
    console.log("componentWillUpdate", nextProps, nextState);
  }

  componentDidUpdate(prevProps, prevState) {
    console.log("componentDidUpdate", prevProps, prevState);
  }
}

    ReactDOM.render(<App name="Mark" />, document.querySelector("#root"))
  </script>	
	</body>
</html>                    

실행 결과

  • $ npx serve
  • 이처럼 shouldComponentUpdate 메소드의 return typetrue로 설정하면 render가 실행되지만 false로 설정하면 이후의 라이프사이클은 실행되지 않습니다.
  • 결국 componentWillUpdate부터 실행되지 않으며 쉽게 말해 업데이트가 실행되지 않음을 의미합니다.

componenetWillReceiveProps

 componentWillReceiveProps(nextProps) {
    console.log("componentWillReceiveProps", nextProps);
  }
  • props를 새로 지정했을 때 바로 호출되며 state의 변경에는 반응하지 않습니다.
  • 해당 라이프사이클에서 props에 따라 state를 변경해야 한다면 setState를 이용하여 state를 변경하면 됩니다.
  • 그러면 다음 이벤트로 각각 가는 것이 아니라 한번에 변경됩니다.

shouldComponentUpdate

 shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate", nextProps), nextState;

    return false;
  }
  • props, state 하나만 변경되거나 둘 다 변경되어도 실행이 됩니다.
  • newPropsnewState를 인자로 하여 호출합니다.
  • return typeBoolean 데이터입니다.
  • 해당 함수를 구현하지 않으면 디폴트 값은 true입니다.
  • truerender되고 falserender가 호출되지 않습니다.

componentWillUpdate

 componentWillUpdate(nextProps, nextState) {
    console.log("componentWillUpdate", nextProps, nextState);
  }
  • 컴포넌트가 재렌더링 되기 직전에 불리며 여기선 setState와 같은 메소드는 사용해선 안됩니다.

componentDidUpdate

 componentDidUpdate(prevProps, prevState) {
    console.log("componentDidUpdate", prevProps, prevState);
  }
  • 컴포넌트가 재렌더링을 마치면 불리는 라이프 사이클입니다.

05.Component Unmounting (언마운트)

componentWillUnmount

 componentWillUnMount() {
     clearInterval(this.interval);
  }
  • 실제로 컴포넌트가 unmount되고 난 후에는 처리할 수 없기때문에 해당 라이프사이클만 활용이 가능합니다.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Example</title>

  <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>  
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

<body>
  <div id="root"></div>
	<script type="text/babel">
   
class App extends React.Component {
  state = {
    age: 24,
  }

  interval = null;

  constructor(props) {
    super(props)

    console.log("constructor", props)
  }
  render() {
    console.log("render")
    return (
      <div>
        <h2>
          Hello {this.props.name} - {this.state.age}
        </h2>
      </div>
    )
  }

  componentWillMount() {
    console.log("componentWillMount")
  }

  componentDidMount() {
    console.log("componentDidMount")

    this.interval =  setInterval(() => {
      this.setState(state => ({...state, age: state.age + 1}))
    }, 1000);
  }

  componentWillReceiveProps(nextProps) {
    console.log("componentWillReceiveProps", nextProps);
  }

  shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate", nextProps), nextState;

    return true;
  }

  componentWillUpdate(nextProps, nextState) {
    console.log("componentWillUpdate", nextProps, nextState);
  }

  componentDidUpdate(prevProps, prevState) {
    console.log("componentDidUpdate", prevProps, prevState);
  }

  componentWillUnMount() {
     clearInterval(this.interval);
  }
}

    ReactDOM.render(<App name="Mark" />, document.querySelector("#root"))
  </script>	
	</body>
</html>
  • setInterval 함수를 componentWillUnMount 메소드에서 해제 시켜줍니다.
  • clearInterval(this.interval); 의 인자값은 setIntervalreturn 값이기 때문에 setInterval을 변수(interval)에 저장시켜 주었다가 interval을 인자값으로 넣어줍니다.
profile
일취월장(日就月將) - 「날마다 달마다 성장하고 발전한다.」
post-custom-banner

0개의 댓글