공부하는 블로그

React | Props & State 본문

React

React | Props & State

치킨닮은닭 2019. 12. 30. 20:24

Props & State

 Props와 State는 리액트의 컴포넌트에서 다루는 데이터로 둘의 차이는 다음과 같다.

 

 props는 부모 컴포넌트가 자식 컴포넌트에게 주는 값으로 자식 컴포넌트에서는 props를 받아오기만 하고 받아온 props를 직접 수정할 수는 없다.

 

 그러면 컴포넌트 내부에서 데이터값을 변경해야하면 어떻게 해야할까? 그때 사용되는 것이 state로 state는 컴포넌트 내부에서 선언하며 내부에서 값을 변경할 수 있는 값이다. 

Props와 State

 

Props

 컴포넌트에서 변하지 않는 데이터가 필요할 때 사용되며 부모 컴포넌트에서 값을 전달할 때에는 자식 컴포넌트 사용 시 < > 안에 <props_name> = 'value'를 넣어 값을 설정한다. 전달된 값을 자식 컴포넌트에서 사용할 때에는 render() 메소드 내부에서 { this.props.<props_name> }의 형식으로 사용한다.

src / App.js

import React from 'react';
import Hello from './components/hello';

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <Hello title='React.js' data='GET Properties!' />
      </div>
    );
  }
}

export default App;

src / components / hello.js

import React, { Component } from 'react';

class Hello extends Component {
  render() {
    return (
      <div>
        <h1>Hello! {this.props.title}!</h1>
        <p>data : {this.props.data}</p>
      </div>
    );
  }
}

export default Hello

 

 

'http://localhost:3000' 페이지 접속 결과

 

 title과 data라는 props를 전달한 결과이다. 부모 컴포넌트인 App.js에서 값을 설정하여 자식 컴포넌트인 hello.js로 전달하였다.

 

 props의 값을 지정해주지 않았을 경우 사용할 기본값을 설정할 수도 있다. 부모 컴포넌트 클래스 하단에 <class_name>.defaultProps = { props_name1 : value1, props_name2 : value2, ... }를 삽입하면 된다.

 

 또한 props의 데이터 타입도 설정할 수 있다. 기본값 설정과 마찬가지로 부모 컴포넌트 클래스 하단에 <class_name>.propTypes = { props_name : React.PropTypes.<data_type> }를 삽입하면 된다.

 

※ React v15.5부터는 React.PropTypes가 다른 패키지로 이동하였다. 대신 prop-types 라이브러리를 이용해야한다.

 

prop-types

Runtime type checking for React props and similar objects.

www.npmjs.com

src / App.js

import React from 'react';
import Hello from './components/hello';

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <Hello title={this.props.title} data={this.props.data}/>
      </div>
    );
  }
}

App.defaultProps = {
  title: 'Default Title',
  data : 'Default Data'
}

export default App;

 

'http://localhost:3000' 페이지 접속 결과

 

State

 State는 컴포넌트 내부에 존재하고 있어 상태값 변경이 가능하므로 유동적인 데이터를 다룰 때 사용한다. 사용 방법은 다음과 같다.

· 초기값 설정 : 생성자(constructor) 메소드에서 this.state = { <state_name> : value }를 통하여 설정한다. 
· 설정된 값 사용 : { this.state.<state_name> }의 형식으로 사용한다.
· 업데이트 : this.setState( { <state_name> : value } ) 메소드를 사용한다. 

 리액트의 state를 이용하여 버튼을 누를 때마다 값이 변하는 카운터를 만들어보자.

 

import React from 'react';

class Counter extends React.Component {
    constructor(props) {
        super(props);
        this.increaseNum = this.increaseNum.bind(this);
        this.decreaseNum = this.decreaseNum.bind(this);
        this.state = {
            number: 0
        }
    }
    
    increaseNum() {
        console.log('increaseNum() is excuted...');
        this.setState({
            number: this.state.number + 1
        });
    }
    
    decreaseNum() {
        console.log('decreaseNum() is excuted...');
        this.setState({
            number: this.state.number - 1
        });
    }
    
    render() {
        return (
            <div>
                <h1>number : {this.state.number}</h1>
                <button onClick={this.increaseNum}>증가</button>
                <button onClick={this.decreaseNum}>감소</button>
            </div>
        );
    }
}

export default Counter

 

 constructor(생성자)에서 this.state를 이용하여 컴포넌트 내부에서 사용할 변수 number의 기본값을 설정해주었다. 또한 컴포넌트에서 사용될 increaseNum()과 decreaseNum()을 바인딩(binding) 해주었다. 만약 바인딩을 해주지 않을 경우 메소드를 render()에서 호출 시 this 객체의 연결이 끊겨 this 객체가 정의되지 않는(undefined) 현상이 발생한다.

 

 그러나, 만약 메소드를 정의할 때 아래의 코드로 정의한다면 바인딩을 생략해도 좋다.

method_name = () => {
    // logics
}

 

 사용자 정의 함수인 increaseNum()과 decreaseNum()에서 this.setState를 이용하여 변수 number의 증가와 감소를 구현하였다.

 

 마지막으로 render()에서 증가와 감소 버튼 클릭 이벤트 발생 시(onClick) 컴포넌트 내에서 정의한 함수를 불러오도록 구현하였다. 만약 이벤트 전달 시 '{ this.increaseNum() }' 식으로 괄호를 포함하여 입력하면 렌더링을 할 때마다 해당 함수가 호출되어 무한루프(rendering → method() → setState → rendering → method() → ···)에 빠져버리므로 주의하자.

 

실행 결과

'React' 카테고리의 다른 글

React | Form  (0) 2020.01.11
React | Event Handling  (0) 2020.01.10
React | React - Node.js 연동하기  (7) 2020.01.07
React | Component  (0) 2019.12.30
React | Introduction  (0) 2019.12.29
Comments