DEV/React

React Component 상위 컴포넌트로부터 갱신된 프로퍼티 값 동기화하기 예제

김슈가 2024. 11. 21. 23:22
728x90
반응형

해당 내용은 컴포넌트의 생명 주기와 관련된 내용이다. 

 

React Component Lifecycle (컴포넌트 생명 주기)

컴포넌트는 생명주기마다 함수를 가지고 있는데 이 함수들을 이용하면 특정 시점에 원하는 동작을 하도록 만들 수도 있다.아래는 App컴포넌트의 자식 컴포넌트인 LifeCycleExample 컴포넌트를 만들

sugarslayer.tistory.com

아래 예제 코드를 통해서 상위 컴포넌트에서 전달받은 프로퍼티 값을 어떻게 동기화 할 수 있는지 살펴보자. 

리액트 서버 구동 시에 최초로 실행되는 index.js에 App 컴포넌트 대신에 AppMakeCounter 컴포넌트를 만들어 예제 구현하였음. 

import React, { Component } from 'react';
import Counter from './03/Counter';
import Counter2 from './03/Counter2';

class AppMakeCounter extends Component {
    constructor(props) {
        super(props);
        this.state = {count:10};
        this.resetCount = this.resetCount.bind(this);
    }
    resetCount(){
        this.setState(({ count }) => ({ count: count + 10 }));
    }
    render() {
        return (
            <div>
                <Counter count={this.state.count}/>
                <Counter2 count={this.state.count}/>
                <button onClick={this.resetCount}>{this.state.count + 10}으로 초기화</button>
            </div>
        );
    }
}

export default AppMakeCounter;

동기화 예제를 위해서 갱신된 프로퍼티값의 동기화를 확인할 수 있는 Counter2, Counter2와 기능은 똑같지만 프로퍼티 값이 동기화 되지는 않는 Counter 프로퍼티를 만들어준다. 

아래는 그냥 버튼을 누르면 1씩 값이 증가하는 Counter 컴포넌트 .

import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: props.count,
    };
    this.increaseCount = this.increaseCount.bind(this);
  }
  increaseCount() {
    // console.log(this.state.count);
    // this.setState({
    //   count: this.state.count + 1,
    // });
    this.setState(({ count }) => ({
      count: count + 1,
    }));
  }
  render() {
    return (
      <div>
        <span>카운트 : {this.state.count}</span>
        <button onClick={this.increaseCount}>카운트 증가</button>
      </div>
    );
  }
}

export default Counter;

아래는 상위 프로퍼티인 AppMakeCounter의 property 값을 동기화해서 AppMakeCounter의 버튼을 누르면 똑같은 값으로 초기화되는 Counter2 컴포넌트 코드이다. 

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Counter2 extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.increaseCount = this.increaseCount.bind(this);
  }
  static getDerivedStateFromProps(props, state) {
    //props는 상위 컴포넌트 AppMakeCounter 에서 전달된 값이고 state는 현재 컴포넌트의 state값이다.
    const { count } = props; //프로퍼티에서 전달된 count 값,
    //프로퍼티에서 전달 받은 count값을 보관한 뒤
    //프로퍼티가 변경되지 않았다면 기존 state값으로 설정한다.
    //프로퍼티가 변경되었다면 변경된 프로퍼티 값으로 설정한다.
    return {
      count,
      newCount: count === state.count ? state.newCount : count,
    };
  }
  increaseCount() {
    this.setState(({ newCount }) => ({
      newCount: newCount + 1,
    }));
  }
  render() {
    return (
      <div>
        현재 카운트: {this.state.newCount}
        <button onClick={this.increaseCount}>카운트 증가</button>
      </div>
    );
  }
}

Counter2.propTypes = {
  count: PropTypes.number,
};

export default Counter2;

위 Counter2 컴포넌트의 코드를 살펴보면 생명주기함수인 getDrivedStateFromProps() 함수로부터 상위 컴포넌트 AppMakeCounter의 갱신된 프로퍼티 값을 동기화한다. 

getDrivedStateFromProps(props, state)에서 인자 props는 상위 컴포넌트에서 전달된 프로퍼티 값을, state는 현재 컴포넌트의 state값을 뜻한다.

728x90
반응형