7. 컴포넌트 LifeCycle

히치키치·2021년 11월 17일
0

React_Basic

목록 보기
6/8
post-thumbnail

라이프사이클

라이프사이클 접두사

  • will : 어떤 작업 작동 실행되는 메서드
  • Did : 어떤 작업 작동 실행되는 메서드

Mount

DOM 생성되고 웹 브라우징에 나타남
Mount 할때 라이프사이클

  1. 컴포넌트 생성
  2. constructor
    컴포넌트 새롭게 만들 때마다 호출되는 클래스 생성자
  3. getDerivedStateFromProps
    props에 있는 값을 state에 동기화
  4. render
    준비한 UI 랜더링
  5. componentDidMount
    컴포넌트가 웹 브라우저에 나타난 후 호출됨

Update

컴포넌트 업데이트하는 경우

  1. props가 바뀔 때
  2. state가 바뀔 때
  3. 부모 컴포넌트가 리랜더링될 때
  4. this.forceUpdate로 강제 랜더링 트리거

Update 할때 라이프사이클

  1. getDerivedStateFromProps
    컴포넌트 props나 state가 바뀌는 경우 호출됨
  2. shouldComponentUpdate
    컴포넌트의 리렌더링 여부 결정
    false 반환시 밑의 과정 수행 X
  3. render
    컴포넌트 리렌더링
  4. getSnapShotBeforeUpdate
    컴포넌트 변화를 DOM에 반영하기 직전에 호출하는 메서드
  5. componentDidUpdate
    컴포넌트 update 작업이 끝난 후 호출하는 메서드

언마운트

컴포넌트를 DOM에서 제거
UnMount 할때 라이프사이클

  1. ComponentWillUnMount

라이프사이클 메서드

render

컴포넌트 랜더링 메서드

render(){....}
  • this.props와 this.state 접근 가능
  • 아무것도 보여주지 않는 경우 : nullfalse 값 반환
  • state 변형 불가
  • 웹브라우저 변형 불가
  • componentDidMount 이용해 DOM 정보 가져오거나 변화 주기

constructor

컴포넌트 생성 메서드 (초기 state 정함)

constructor(props){
	super(props);
  	console.log("constructor");
}

getDerivedStateFromProps

컴포넌트 Mount/update할 때, props로 받아온 값을 state에 동기화

static getDrivedStateFromProps(nextProps,prevState){
  if(nextProps.value!==prevProps.value){
    //조건에 따른 특정 값 동기화
    return {value : nextProps.value}
  }
  return null;
  //state 변경 필요 없는 경우 null 반환
}

componentDidMount

컴포넌트 생성과 첫 렌더링 마친 후 실행됨

componentDidMount(){....}
  • 비동기식 작업 처리됨
    (ex. 이벤트 등록, setTimeOut, setInterval, 네트워크 요청, 다른 라이브러리 함수 등 )

shouldComponentUpdate

props/state 변경시, 리렌더링 시작 여부 지정함

shouldComponentUpdate(nextProps,nextState){....}
  • 컴포넌트 생성시, 따로 메서드 생성하지 않으면 기본적으로 true 반환해 렌더링 진행
  • false 반환하는 경우, 업데이트 과정 중지됨

getSnapshotBeforeUpdate

render() 호출 후, DOM에 변화 반영하기 직전에 호출

getSnapShotBeforeUpdate(preProps,prevState){
  if(preState.array!==this.state.array){
    const {scrollTop,scrollHeight}=this.list
    return {scrollTop, scrollHeight}
  }
}
  • 반환하는 값은componentDidUpdate의 snapshot 파라미터로 전달 가능
  • 업데이트 직전 값을 참고할 때 활용
    (ex. 스크롤바 위치 유지)

componentDidUpdate

리렌더링 완료 후 실행

shouldComponentUpdate(prevProps,prevState,snapShot){....}
  • 업데이트 끝났으니 DOM 관련 처리 무방

componentWillUnmount

컴포넌트를 DOM에서 제거

componentWillUnMount(){....}
  • componentDidMount에서 등록한 것을 여기서 제거 작업 진행

라이프사이클 메서드 사용 예제

1. LifeCycleSample 컴포넌트 생성

  • 각 라이프사이클 메서드 실행할 때마다 콘솔에 기록
import React, {Component} from 'react';

class LifeCycleSample extends Component{
    
    //state 생성
    state={ 
        number:0,
        color:null
    }

    //ref 설정
    myRef=null;
    
    //컴포넌트 생성 시 실행되는 클래스 생성자 메서드로 state 초기값 설정
    constructor(props){
        super(props);
        console.log("constructor");
        //color : "#000000" 가져옴
    }

    //props로 받아 온 값을 state에 동기화
    static getDerivedStateFromProps(nextProps,prevState){
        if(nextProps.color!==prevState.color){
            console.log("getDerivedStateFromProps");
            return {color : nextProps.color};
        }
        return null;
    }

    //컴포넌트 생성 후, 첫 렌더링 후 실행됨
    componentDidMount(){
        console.log("componentDidMount");
    }

    shouldComponentUpdate(nextProps,nextState){
        console.log("shouldComponentUpdate",nextProps,nextState);
        //숫자 마지막 자리가 4이면 리렌더링 안함
        return nextState.number %10!==4;
    }

    componentWillUnmount(){
        console.log("componentWillUnmount");
    }

    //render 후 DOM에 변화 반영 직전에 호출
    //DOM 변화 직전의 color props를 snapshot 값을 반환해서 componentDidUpdate에서 조회 가능
    getSnapshotBeforeUpdate(prevProps,prevState){
        console.log("getSnapshotBeforeUpdate");
        if(prevProps.color!==this.props.color){
            return this.myRef.style.color;
        }
        return null;
    }

    componentDidUpdate(prevProps,prevState,snapshot){
        console.log("componentDidUpdate",prevProps,prevState);
        if(snapshot){
            console.log("업데이트 되기 직전 색성 : ",snapshot);
        }
    }

    handleClick=()=>{
        this.setState({
            number:this.state.number+1
        });
    }

    render(){
        const style={
            color:this.props.color
        };
    
        return(

            <div>
                <h1 style={style} ref={ref=>this.myRef=ref}>
                    {this.state.number}
                </h1>
                <p> color : {this.state.color}</p>
                <button onClick={this.handleClick}>
                    더하기
                </button>
            </div>

        )
    }
}

export default LifeCycleSample;

2. App에 랜더링



import './App.css';
import React,{Component} from 'react';
import LifeCycleSample from './LifeCycleSample';


function getRandomColor(){
  return "#"+Math.floor(Math.random()*16777215).toString(16);
}

class App extends Component{

  state={
    color:"#000000"
  }

  handleClick=()=>{
    this.setState({
      color:getRandomColor()
    });
  }

  render(){
    {

      return (
        <div>
          <button onClick={this.handleClick}> 랜덤 색상</button>
          {/*1. 버튼 렌더링
             2. 버튼 클릭시 handleClick -> getㄲandomcolor 메서드 실행됨*/}
          <LifeCycleSample color={this.state.color}/>
          {/*3. LifeCycleSample 컴포넌트의 color 값을 props로 설정*/ }
        </div>
      );
    }
  }
}


export default App;

3. 버튼 누르고 콘솔창 관찰

첫 화면

  1. constructor
  • LifeCycleSample는 리액트의 Component 클래스 상속함
  • constructor(생성자) 메서드 따로 생성함
    리액트의 Component 클래스의 생성자 사용 X
  • 컴포넌트 내부에서 값을 설정하는 state의 초깃값(number와 color 값) 설정
  1. getDerivedStateFromProps
  • 부모 class인 App에서 받아온 props 값을 자식 클래스인 LifeCycleSample의 state로 동기화
  1. componentDidMount
  • 컴포넌트 생성 -> 마운트된 후 -> 첫 렌더링 진행된 후

랜덤 색상 버튼 클릭

  1. getDerivedStateFromProps
  • 버튼 onClick 이벤트 발생
    : 랜덤으로 색상 코드 반환하는 getRandomColor 메서드 실행됨
  • 부모 class인 App에서 받아온 props 값 (메서드로 반환받은 색상 코드 color 값):
    LifeCycleSample 컴포넌트의 color 값을 props로 설정
  • props로 받아 온 값을 state에 동기화
  1. shouldComponentUpdate
  • 현재 state/props 변화가 컴포넌트 출력 결과에 영향을 미치는지 여부 확인
  • 변화 발생시 기본적으로 true 반환해 componentDidUpdate 실행됨
  • false 반환시 componentDidUpdate와 render 실행 안 됨
  1. getSnapshotBeforeUpdate
  • update 전 가장 마지막 렌더링 결과가 DOM 등에 반영되었을 때에 호출
  • DOM으로부터 스크롤 위치 등과 같은 정보를 update 되기 전에 얻을 수 있음
  • componentDidUpdate에 인자로 전달됨
  1. componentDidUpdate
  • update이 일어난 직후에 호출
  • 첫 렌더링에서는 호출되지 않음

더하기 버튼 클릭

  • 위의 랜덤 색상 변경 버튼 클릭시와 동일한 흐름
  • 변경된 색상 코드는 부모 클래스인 App에서 props로 받아와 state로 설정해 getDerivedStateFromProps 이 있었지만 number를 +1하는 메서드는 LifeCycleSample 클래스 내부에서 state로 진행되기 때문에 사용 X

숫자의 마지막 자리가 4인 경우 update 취소

shouldComponentUpdate(nextProps,nextState){
    console.log("shouldComponentUpdate",nextProps,nextState);
    //숫자 마지막 자리가 4이면 리렌더링 안함
    return nextState.number %10!==4;
}
  • shouldComponentUpdate에서 4가 아닌 경우에만 true 반환함
    ->update/re-rendering 진행됨
  • 현재 number가 4임으로 false가 반환됨
    getSnapshotBeforeUpdatecomponentDidUpdate 실행 안됨

React.Component 공식 문서

https://ko.reactjs.org/docs/react-component.html#componentdidupdate

0개의 댓글