TIL. State
State
컴포넌트에서 유동적인 데이터를 다룰 때, state를 사용한다. React.js 어플리케이션을 만들 땐, state를 사용하는 컴포넌트의 갯수를 최소화 하는 것을 노력해야한다. 예를들어 10개의 컴포넌트에서 유동적인 데이터를 사용 하게 될 땐, 각 데이터에 state를 사용 할 게 아니라, props를 사용하고 10개의 컴포넌트를 포함시키는 container 컴포넌트를 사용하는 것이 효율적이다.
기본적인 사용방법
StateExample.js
import React from 'react';
class StateExample extends React.Component {
constructor(props) {
super(props);
this.state = {
header: "Header Initial state",
content: "Content Initial State"
};
}
updateHeader(text){
this.setState({
header: "Header has changed"
});
}
render() {
return (
<div>
<h1>{this.state.header}</h1>
<h2>{this.state.content}</h2>
<button onClick={this.updateHeader.bind(this)}>Update</button>
</div>
);
}
}
export default StateExample;
- state의 초기 값을 설정 할 때는 constructor(생성자)메소드에서 this.state= {}를 통하여 설정한다.
- state를 렌더링 할 때는 {this.state.stateName} 을 사용한다.
- state를 업데이트 할 때는 this.setState() 메소드를 사용한다. ES6 class에선 auto binding이 되지 않으므로, setState 메소드를 사용하게 될 메소드를 bind 해주어야 한다. (bind하지 않으면 React Component가 가지고 있는 멤버 함수 및 객체에 접근 할 수 없다.)
적용: State와 Props
유동적인 데이터를 렌더링하며, parent컴포넌트와 communication 하는 예제 컴포넌트 RandomNumber를 만들어보자
RandomNumber.js
import React from 'react';
import ReactDOM from 'react-dom';
class RandomNumber extends React.Component {
updateNumber(){
let value = Math.round(Math.random()*100);
this.props.onUpdate(value);
}
constructor(props){
super(props);
this.updateNumber = this.updateNumber.bind(this);
}
render(){
return (
<div>
<h1>RANDOM NUMBER: { this.props.number }</h1>
<button onClick={this.updateNumber}>Randomize</button>
</div>
);
}
}
export default RandomNumber;
랜덤 숫자를 나타내는 h1 element와, 클릭하면 새로운 랜덤값으로 바꾸는 button element를 렌더링한다.
이 컴포넌트에서는 두가지 prop을 사용한다
- number: 랜덤 값
- onUpdate: function 형태의 prop으로서, parent 컴포넌트에 정의된 메소드를 실행 할 수 있게 한다.
이제, parent컴포넌트인 app컴포넌트에서 RandomNumber 컴포넌트를 사용해보자
app.js
import React from 'react';
import ReactDOM from 'react-dom';
import Header from './Header';
import Content from './Content';
import RandomNumber from './RandomNumber';
class App extends React.Component {
constructor(props){
super(props);
this.state = {
value: Math.round(Math.random()*100)
};
this.updateValue = this.updateValue.bind(this);
}
updateValue(randomValue){
this.setState({
value: randomValue
});
}
render(){
return (
<div>
<Header title={ this.props.headerTitle }/>
<Content title={ this.props.contentTitle }
body={ this.props.contentBody }/>
<RandomNumber number={this.state.value}
onUpdate={this.updateValue} />
</div>
);
}
}
App.defaultProps = {
headerTitle: 'Default header',
contentTitle: 'Default contentTitle',
contentBody: 'Default contentBody'
};
export default App;