[5장]Component의 props와 propsType 그리고 state
Component로 개발하면 Component간 데이터를 주고 받거나 서버로 부터 가져온 값을 처리해서 관리하는 것은 필수 적이다. React에서는 Component에서 데이터의 상태를 관리하는 몇가지 특징이 있는데 알아보자.
props
부모 Component가 자식 Component로 전달한 값이 저장되는 객체이며, props는 읽기 전용이므로 수정이 불가능하다.
//in ParentComponent.js
import React from 'react';
import ChildComponent from './ChildComponent';
class ParentComponent extends React.Component {
render() {
return (
<ChildComponent sendValue="1"></ChildComponent>
)
}
}
//in ChildComponent.js
export default ParentComponent;
import React from 'react';
class ChildComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<h1>이 값은 부모로 부터 전달 된 {this.props.sendValue}</h1>
)
}
}
export default ChildComponent;
//in App.js
import React from 'react';
import ParentComponent from './component/ParentComponent';
function App() {
return (
<ParentComponent></ParentComponent>
);
}
export default App;
위 내용을 보면 ParentComponent에서 ChildComponent를 생성하면서 sendValue라는 값을 전달 해주는 데, 이렇게 ParentComponent로 부터 전달 된 sendValue라는 값은 ChildComponent의 props객체 안에 sendValue라는 값으로 저장된다. 이렇게 전달된 값에 this.props.sendValue로 접근하여 사용가능하다.
import React from 'react';
class ChildComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
this.props.sendValue = 2
return (
<h1>이 값은 부모로 부터 전달 된 {this.props.sendValue}</h1>
)
}
}
export default ChildComponent;
만약 위와 같이 읽기 전용인 props의 내용을 변경하고자 하면 어떻게 될까??
다음과 같은 오류 메시지를 볼 수 있다.
propTypes
Component로 전달되는 값들에 대해서 유효성 체크 및 제약조건을 다루는 것은 매우 중요하다. 이를 제공하기 위해서 React에서는 propTypes를 제공하는데 어떻게 사용하는지 설명한다.
import React from 'react';
import PropTypes from 'prop-types';
class UserPropTypesChildComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>이 값은 부모로 부터 전달 된 {this.props.sendValue}</h1>
</div>
)
}
}
//1. 데이터 유효성 검사하기
UserPropTypesChildComponent.propTypes = {
sendValue: PropTypes.number.isRequired,
sendValueRangeCheck: function(props) {
if(props['sendValue'] > 100) {
return new Error('sendValue는 100이하');
}
}
}
//2. 초기 Props값
UserPropTypesChildComponent.defaultProps = {
name: '우현'
}
export default UserPropTypesChildComponent;
- 데이터 유효성 검사하기 위와 같이 전달되는 값에 대한 타입 및 범위를 지정해서 처리 할 수 도 있다. 하지만 문제는 저렇게 유효성 체크가 되어도 콘솔로그에 아래와 같은 Warning을 출력하고 render 함수는 동작한다.
- 초기 Prop값
state
props가 읽기 전용이기 때문에 전달 받은 Component가 전달 된 sendValue라는 값을 가공해서 바로 저장 할 수 가 없다. 이렇듯이 Component에서 가공된 값들을 다룰 땐 state를 사용하여야 한다.
import React from 'react';
class ChildComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
sendValue: Number(this.props.sendValue)
}
setInterval(() => {
this.setState({
sendValue: this.state.sendValue + 1
});
//this.state.sendValue= this.state.sendValue + 1; #이렇게 사용하면 화면 갱신이 발생하지 않는다.
}, 1000)
}
render() {
return (
<div>
<h1>이 값은 부모로 부터 전달 된 {this.props.sendValue}</h1>
<h1>이 값은 가공된 {this.state.sendValue}</h1>
</div>
)
}
}
export default ChildComponent;
state의 정의는 생성자와 클래스 필드로 할 수 있지만, 설명에서는 생성자에서 정의하는 것으로 설명한다. state 정의는 따로 설명할 것은 없고 state의 값을 변경하는 부분에 대해서 조금 짚고 넘어갈 필요가 있다. React에서는 state값을 변경하도록 하기 위해 setState라는 함수를 제공하고 이 함수에 state에서 변경하고자 하는 값에 대해 Object로 넘겨 주면 state 변경이 발생한다.
여기서 주의 할 점은 주석 부분에 대한 설명이다. state에 대한 값을 setState 함수를 사용해서 변경하지 않고 직접 property에 접근해서 값을 수정해 버리면 state의 값은 변경이 발생하나, Component의 변화는 발생하지 않는다. 이유는 직접적인 변경에 대해서는 React에서 감지를 하지 못하기 때문이다. this.state를 지정할 수 있는 공간은 생성자에서만 가능하다는 것을 알고 있자.
그리고 setSate를 사용하지 않는다면, 빌드 도구에 의한 Component 최적화(추후 설명)에 대한 헤택도 볼 수 가 없게 된다.
또, this.state가 비동기적으로 업데이트 될 수 있기 때문에 this.setState({sendValue: this.state.sendValue + 1});과 같이 사용하기 보다는 아래와 같이 사용하는게 안전하다.
//인자로 전달되는 state는 이전 state
//props는 업데이트가 적용된 시점의 props
this.setState((state, props) => ({
sendValue: state.sendValue + 1
}));
정리
React에서 Component로 전달 된 값을 어떻게 관리하는지에 대한 props와 state를 알아보았다. 다음에는 Component의 생명 주기에 대해서 알아보자.
Comments