본문 바로가기

Javascript/React

Props, State (리액트 컴포넌트 속성, 상태)

반응형

Props, State (리액트 컴포넌트 속성, 상태)

Properties(속성)의 Props이다. 리액트에서 변동하지 않는 데이터를 다룰 때 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import logo from './logo.svg';
import './App.css';
 
class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          <div>이름은 {this.props.name} 이고, 나이는 {this.props.age} 입니다.</div>
        </p>
      </div>
    );
  }
}
 
App.PropTypes = {
  name : PropTypes.string,
  age : PropTypes.number.isRequired,
};
App.defaultProps = {
  name : '정프로',
}
export default App;
 


위 예제는 create-react-app 으로 만든 소스코드에서 App.js를 수정한 코드다.

수정한 부분만 보면 Props를 사용하기 위해서 'prop-types'를 npm으로 설치한 다음에 'prop-types' 모듈을 불러왔다.

props로 정적인 데이터를 받아 사용할 수 있다. '{ }' 를 이용해서 {this.props.name} 이런식으로 사용하면 된다.

1
ReactDOM.render(<App name="정아마추어" age={26/>, document.getElementById('root'));


기존에 <App />만으로 컴포넌트를 만들었다면 이제 props를 적용하기 위해서 데이터를 위와 같이 넘겨 줄 수 있다.

[결과]

다시 제일 위의 예제를 보면 이런 데이터가 넘어 올 때 타입을 엄격하게 지정할 수 있다.

name : PropType.string 처럼 name이라는 데이터는 string타입으로 넘어 오게 검사하는 형식이다.

.isRequired를 사용해서 반드시 데이터를 넘겨 받아야만 하게 만들 수 있고

.defaultProps 를 정의해서 별 다른 입력이 없을 때 default로 사용할 데이터를 미리 정의해놓고 사용할 수도 있다.

* 앞으로 리액트를 할 때 Props를 아주 자주 잘 사용해야 한다.

Props는 외부에서 오는 데이터이므로 컴포넌트 내부에서 변경하면 안된다.

Props는 부모의 컴포넌트로 부터 받아 사용될 수 있다. 위 예제처럼 직접 <App name="" ~~ /> 로 받은 App.js뿐만 아니라 그 자식 컴포넌트를 만드는 곳에서도 Props를 사용할 수 있다.

컴포넌트 내에서 관리해야할 데이터가 있다면 State를 사용해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
React.PropTypes.array           // 배열
React.PropTypes.bool.isRequired // Boolean, 필수
React.PropTypes.func            // 함수
React.PropTypes.number          // 정수
React.PropTypes.object          // 객체
React.PropTypes.string          // 문자열
React.PropTypes.node            // Render가 가능한 객체
React.PropTypes.element         // React Element
React.PropTypes.instanceOf(땡땡땡) // 땡땡땡클래스의 instance 인지
React.PropTypes.oneOf(['jeong''pro']) // jeong 또는 pro
React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.array]) // 문자열 또는 배열
React.PropTypes.arrayOf(React.PropTypes.string)  // 문자열을 원소로 가지는 배열
React.PropTypes.objectOf(React.PropTypes.string) // 문자열을 값으로 가지는 객체
React.PropTypes.shape({                          // 지정된 형식을 충족하는지
  color: React.PropTypes.string,
  fontSize: React.PropTypes.number
});
React.PropTypes.any.isRequired  // 어떤 타입이든 가능하지만 필수



PropTypes 종류는 위와 같다. 이외에 커스텀으로 PropType을 정의해서 사용할 수도 있다.


State

State는 텍스트필드의 값처럼 사용자에 의해 변경되는 값을 관리할 때 주로 사용된다.

즉, 컴포넌트에서 유동적인 데이터를 다룰 때!

(*****미리 말하자면, state 사용을 최대한 줄이는 것이 리액트에서 효율적임.)

컴포넌트에서 관리하거나 가지고 있어야할 상태가 필요할 때 생성하면된다.

(보통 컴포넌트 클래스에서 생성자로 정의함)

1
2
3
4
5
6
7
8
9
class App extends Component {
  constructor(){
    super();
    this.state = {
      score : 0
    };
  }
  //...생략...
}
cs

위의 예제처럼 score라는 상태를 만들어서 관리하면 되고 사용은 Props와 똑같이 {this.state.score} 이런식으로 사용하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class App extends Component {
  constructor() {
    super();
    this.state = {
      score: 0,
    };
  }
 
  plusscore() {
    this.setState((prevState, props) => {
      return { score: prevState.score + 1 }
    });
  }
 
  render() {
    return (<button
              onClick={() => this.plusscore()}
            >
              Score : {this.state.score}
            </button>);
  }
}


state 상태를 변경시킬 때는 반드시 setState()를 사용해야 한다. 


결과적으로 요약하면

Prop : 컴포넌트에서 필요한 정적 데이터, 변하지 않는 값으로 사용한다. 컴포넌트 내에서 변경해선 안된다.

State : 컴포넌트에서 필요한 동적 데이터, 사용자에 의해 변경되는 것을 관리할 때 사용하거나 상태를 저장해야할 때 사용하고, 컴포넌트 내에서 변경된다. 변경할 때는 반드시 setState()를 사용해야한다.

더 유용하게 사용하는 것은 추후에 알아본다. 특히 state 사용을 줄이면서 props로 전환하는 것.



반응형

'Javascript > React' 카테고리의 다른 글

React 바인딩(이벤트/메서드 연결)  (0) 2017.10.17
JSX (React Component)  (2) 2017.10.11
리액트(React) 환경 설정 (create-react-app)  (2) 2017.10.09
리액트(React)  (0) 2017.10.08