본문 바로가기

React

Props 와 State




이번 포스팅은 React의 State 와 Props 에 대해서 정리 해보려고 합니다.


State 와 Props는 React Component 에서 빠질 수 없는 기본적이면서 중요한 개념입니다. 이 두 가지 개념을 이용하여 부모 컴포넌트와 자식 컴포넌트 간 데이터를 전달 하고 컴포넌트의 데이터를 변화 시킵니다. 그렇기 때문에 다들 아시겠지만 이 두 개념은 처음 리액트를 접하거나 배우게 되면 항상 묶여져 있습니다.



Props


Props 는 properties 의 줄임말 입니다. 

Props는 Component 로 데이터를 전달 합니다. 



render (
<div>
<MoviePoster posterUrl="[image_url]" title="title"/>
<h1>Hello movies!</h1>
<h6>{this.props.title}</h6>
</div>
)


class MoviePoster extends Component {
render() {
return (
<img src={this.props.posterUrl}/>
<h6>{this.props.posterUrl}</h6>
);
}
}


위 코드와 같이 Props는 데이터를 컴포넌트 간 전달 하기 위해 쓰여집니다.

여기서 주의 할 점은 Props는 setProps와 replaceProps로 변경이 가능 했지만 지금은 지원을 하지 않습니다. Props는 단지 데이터를 전달 하기 위해 쓰일 뿐 데이터를 변경 하지는 않습니다 즉, Props가 입력 되면 항상 동일한 출력으로 렌더링 되어야 합니다.



State


State는 데이터를 유지하고 저장합니다. 데이터를 유지한다라는 측면에서 보면 Props와 같습니다. 차이점은 State는 컴포넌트내에서 생성하고 활동한다. 그리고 데이터를 변경 할 수 있습니다. 아래 코드는 클릭을 하면  클릭 수를 카운터하는 코드입니다.



class Button extends React.Component {
constructor() {
super();
this.state = {
count: 0,
};
}

updateCount() {
this.setState((prevState, props) => {
return { count: prevState.count + 1 }
});
}

render() {
return (<button
onClick={() => this.updateCount()}
>
Clicked {this.state.count} times
</button>);
}
}



위 코드를 보면 알 수 있듯 state는 컴포넌트 내에 state ={} 이와 같이 초기화 할 수 있으며, 중간에 setTimeout 안에서 사용 된 setState() Function을  사용 하여 업데이트 할 수 있습니다. 참고로 this 키워드는 this가 어디에 위치하느냐에 따라 가르키는게 달라지는데 지금 코드상에서는 현재 컴포넌트를 가르키고 있다고 보시면 됩니다. 그럼 코드를 잘라서 보겠습니다.


State 생성


constructor() {
super();
this.state = {
count: 0,
};
}


위 코드는 state를 생성하는 코드입니다. 원문에서는 constructor에서 생성하여야 한다고 나와 있지만 



class App extends Component {
state = {};
}


테스트 해보니 위와 같이 생성 해도 되는 거 같습니다.



State 변경 할 수 있다.


updateCount() {
this.setState((prevState, props) => {
return { count: prevState.count + 1 }
});
}


클릭이 되면 updateCount() 가 호출 되고 setState() 를 통해 state가 업데이트 됨을 알 수 있습니다. 그리고 state가 업데이트 되면 


render() {
return (<button
onClick={() => this.updateCount()}
>
Clicked {this.state.count} times
</button>);
}


render() 가 실행 되면서 다시 렌더링 됩니다. State가 변화가 일어나면 항상 자동으로 실행되면서 다시 렌더링 됩니다. 그런데 여기서 두 가지 주의 할 점이 있습니다.


첫 번째!


코드를 보시서 this.state.count = this.state.count + 1; 이렇게 "state를 직접 변경하면 되는거 아니야?"

라고 생각 하실 수 있습니다. 하지만 이렇게 하게 되면 React는 state의 변화를 감지 하지 못하게 되어 다시 렌더링 하지 않습니다.

그렇게 되면 state가 변경 되었다하더라도 화면상으로는 값이 변경 되지 않게 되는 것이죠


두 번째!



// DO NOT USE
this.setState({
    count: this.state.count + 1
});


위 코드는 문제가 없는 코드라 느끼실 수 있겠지만 이는 setState()의 비동기 성질을 고려 하지 않았으며, 동기화 되지 않은 상태의 데이터를 사용 할 수 있기 때문에 오류를 발생 시킬 수 있습니다. 



추가적으로 React는 Component를 꼭 Class로 만들어야 하는 것은 아닙니다. Function 을 이용해서도 Component를 만들 수 있습니다.


Dumb Component and Smart Component



/**
* Movie box
* @param {string} title movie title
* @param {string} posterUrl movie poster image url
*/
function Movie({title, posterUrl}) {
return (
<div className="wrap-movie">
<div className="box-movie">
<MoviePoster poster={posterUrl}/>
</div>
<div className="box-movie">
<h1>Hello movies!</h1>
<h6>{title}</h6>
</div>
</div>
)
}


/**
* Movie poster component
* @param {string} poster movie poster image
*/
function MoviePoster({poster}) {
return (
<img src={poster} alt="Movie Poster" />
)
}


이렇게 Functional Component를 이용 할 수 있는데 Functional Component는 Dumb컴포넌트라고 불립니다. 그 이유는 State를 가지고 있지 않기 때문입니다. Props만 가지고 있습니다. 그래서 Stateless Component 라고 불리기도 합니다. 반대로 Class 로 만들어진 Component는 Smart 컴포넌트로 불립니다. 그래서 독립적으로 state가 있어야 하고 단독으로 재렌더링이 필요한 컴포넌트가 아닌 부모 컴포넌트에 단순히 종속되어 있는 컴포넌트는 Functional Component로 작성하는 것이 효율적인 코드가 될 것이라고 생각 된다. 



이상 포스트를 마치겠습니다. 다음 시간에는 React의 Life Cycle에 대해서 알아 보겠습니다.


혹시 보시면서 불편하거나 잘못 된 점을 발견 하신 고수님들은 언제든 지적 부탁 드립니다!





[Reference- http://lucybain.com/blog/2016/react-state-vs-pros/

'React' 카테고리의 다른 글

React의 Life Cycle  (0) 2018.07.14
React 란 무엇 일까?  (0) 2018.07.13