Step by Step

React Study(6) - 리액트를 다루는 기술 7장 본문

React

React Study(6) - 리액트를 다루는 기술 7장

짤진이 2023. 1. 31. 15:03
반응형

#7장 컴포넌트의 라이프사이클 매서드
모든 리액트 컴포넌트에는 라이프사이클이 존재합니다. 컴포넌트의 수명은 페이지에 렌더링되기 전인 준비 과정에서 시작하여 페이지에서 사라질 때 끝납니다.
이 때는 컴포넌트의 라이프사이클 메서드를 사용합니다.
참고로 라이프 사이클 메서드는 클래스형 컴포넌트에서만 사용할 수 있습니다.

업데이트를 발생시키는 뇨인
props 변경, state 변경, 부모 컴포넌트 리렌더링 => getDerrivedStateFromProps =>shouldComponentUpdate 
=> true 반환 시 render 호출, false 반환 시 여기서 작업 취소 => render => getSnapshotBeforeUpdate
=> componentDudUpldate

7.2 라이프사이클 메서드 살펴보기
render()함수
컴포넌트 모양새를 정리합니다. 이 메서드 안에서는 this.prop 이나 this.state에 접근할 수 있으며 리액트 요소를 반환합니다.
아무것도 보여주고 싶지 않다면 null값이나 false값을 보여주도록 하세요.

constructor 메서드
constructor(props)
이것은 컴포넌트의 생성자 메서드로 컴포넌트를 만들 때 처음으로 실행됩니다.
이 메서드에서는 초기 state를 설정할 수 있습니다.

getDerrivedStateFromProps 메서드
getDerrivedStateFromProps 메서드는 props로 받아 온 값을 state에 동기화 시키는 용도로 사용하며 컴포넌트가 마운트될 때와 업데이트 될 떄 호출됩니다.

componentDidMount 메서드
이것은 컴포넌트를 만들고 첫 렌더링을 다 마친 후 실행합니다.

shouldComponentUpdate 메서드
이것은 props 또는 state를 변경했을 때, 리렌더링을 시작할지 여부를 지정하는 메서드입니다. 이 메서드에서는 반드시 true 값 또는 false값을 반환해야합니다.

getSnapshotBeforeUpdate
주로 업데이트하기 직전의 값을 참고할 일이 있을 때 사용한다.

componentDidMount
prevProps, prevState을 사용하여 데이터에 접근할 수 있다.

componentWillUnmount
이것은 컴포넌트를 DOM에서 제거할 때 실행한다.

7.3 라이프사이클 메소드 사용하기
LifeCycleSample 컴포넌트 만들기 => App에 렌더링하기 => 버튼 누르고 콘솔 창 관찰하기

import {Component} from 'react';

class LifeCycleSample extends Component {
    state = {
        number : 0,
        color : null,
    }
    MyRef = null;
    
    constructor(props){
        super(props);
        console.log('constructor');
    }
    static getDerivedStateFromProps(nextProps, prevState){
        console.log('getDerivedStateFromProps')
        if (nextProps.color !== prevState.color){
            return {color:nextProps.color};
        }
        return null;
    }
    componentDidMount() {
        console.log('componentDidMount');
    }
    shouldComponentUpdate(nextProps, nextState) {
        console.log('shouldComponentUpdate',nextProps, nextState);
        return nextState.number % 10 !== 4;
    }
    componentWillUnmount(){
        console.log('componentWillUnmount')
    }
    handleClick = () => {
        this.setState({
            number: this.state.number+1
        });
    }
    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);
        }
    }
    render(){
        console.log('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;


7.3.1
예제 컴포넌트 생성
<LifeCycleSample.js>

import {Component} from 'react';

class LifeCycleSample extends Component {
    state = {
        number : 0,
        color : null,
    }
    MyRef = null;
    
    constructor(props){
        super(props);
        console.log('constructor');
    }
    static getDerivedStateFromProps(nextProps, prevState){
        console.log('getDerivedStateFromProps')
        if (nextProps.color !== prevState.color){
            return {color:nextProps.color};
        }
        return null;
    }
    componentDidMount() {
        console.log('componentDidMount');
    }
    shouldComponentUpdate(nextProps, nextState) {
        console.log('shouldComponentUpdate',nextProps, nextState);
        return nextState.number % 10 !== 4;
    }
    componentWillUnmount(){
        console.log('componentWillUnmount')
    }
    handleClick = () => {
        this.setState({
            number: this.state.number+1
        });
    }
    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);
        }
    }
    render(){
        console.log('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;



<App.js>

import {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>
        <LifeCycleSample color={this.state.color}/>;
      </div>
    )
  }
}
export default App;


이 컴포넌트는 각 라이프사이클 메서드를 실행할 때마다 1씩 더하고 색상이 바뀝니다.
getDerivedStateFromProps는 부모에게서 받은 color 값을 state에 동기화하고 있다.
getSnapshotBeforeUpdate은 DOM에 변화가 일어나기 직전의 색상 속성을 snapshot 값으로 반환한다.

7.4 정리
라이프사이클 메서드는 컴포넌트 상태에 변화가 있을 때마다 실행되는 메서드입니다. 이 메서드들은 DOM을 직접 건드려야하는 상황에서 유용합니다.

 

라이프 사이클

반응형