super()
함수를 호출해야하며, super()
함수의 매개변수로 props를 할당한다.render()
함수 내부에서 this.state.[상태]
형식으로 state 객체에 접근한다.class User extends React.Component {
constructor(props) { // props를 매개변수로 생성자를 호출
super(props);
// 생성자 내부에 state 객체 생성
this.state = {
name: 'Kim',
age: 22,
number: '010-1111-2222'
};
}
render() {
return ( // state 조회하기
<div>
<h1>Hello World</h1>
<p>{this.state.name}</p>
<p>{this.state.age + 1}</p>
<p>{this.state.number}</p>
</div>
)
}
}
ReactDOM.render(
<User/>,
document.getElementById('app')
);
class User extends React.Component {
state = {
name: 'Kim',
age: 22,
number: '010-1111-2222'
};
render() {
// 비구조화 할당 사용
const { name, age, number } = this.state;
return (
<div>
<h1>Hello World</h1>
<p>{name}</p>
<p>{age + 1}</p>
<p>{number}</p>
</div>
)
}
}
ReactDOM.render(
<User/>,
document.getElementById('app')
);
shouldComponentUpdate()
)을 타게 된다.this.setState({myKey: 'my new value'});
this.setState((prevState, props) => {
return {myInteger: prevState.myInteger + props.step};
});
setState()
의 두번 째 매개변수인 callback은 optional이며, updater의 자료형과 상관없이 사용 가능하다.// when updater is Object
this.setState({myKey: 'my new value'}, () => {
console.log('setState complete');
});
// when updater is Function
this.setState((prevState, props) => {
return {myInteger: prevState.myInteger + props.step};
}, () => {
console.log('setState complete');
});
setState()
함수로 state 변경이 완료되고 component가 re-rendered된 이후 호출된다. 따라서, re-rendered이후의 어떤 확인이나 동작이 필요할때 간단히 기술해서 사용 가능하다.componentDidUpdate()
을 사용하라고 추천하고 있다.state는 반드시 setState()
함수를 이용해서 변경해야 한다.
setState()
함수를 이용하여 변경해야 한다.// state를 직접 변경하는 경우 - react가 state 변경을 감지하지 못한다.
this.state.comment = 'Hello';
// setState()로 state를 변경한 경우 - react가 감지
this.setState({comment: 'Hello'});
setState()
는 state를 변경(update)하는 것이 아닌 병합(merge)한다.
constructor(props) {
super(props);
this.state = {
posts: [],
comments: []
};
}
componentDidMount() {
fetchPosts().then(response => {
this.setState({ // posts를 업데이트 하는 거기 때문에 comment에 영향X
posts: response.posts
});
});
fetchComments().then(response => {
this.setState({
comments: response.comments
});
});
}
setState()
는 비동기로 작동한다.
setState()
을 여러번 호출 할 경우 이를 단일 업데이트로 한꺼번에 처리한다. 즉 setState()
는 즉시 값을 merge하지 않고, pending된 형태로 동작한다. 따라서 setState()
호출후 this.state
로 값을 확인했을때, 값이 변경되어 있을 수도 있고, 안되어 있을 수도 있다.this.props
와 this.state
가 비동기적으로 업데이트될 수 있기 때문에 state변경이 이전 state에 의존적인 경우 업데이트가 제대로 이루어지지 않을 수 있다. 때문에 이 경우에는 매개변수가 Function인 setState()
함수를 사용하여 이전 값을 참조하여 state를 업데이트 하는 것이 좋다.// state 변경이 이전 state나 props를 참조할 경우
// 이 방식은 업데이트가 제대로 이루이지지 않을 수 있다.
this.setState({
counter: this.state.counter + this.props.increment,
});
// 이 경우에는 Function을 매개변수로 갖는 방식으로 state를 변경해야 한다.
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
setState()
을 호출하고나면, component life cycle 함수인 shouldComponentUpdate()
가 호출된다. setState()
을 호출했다고 해서, 항상 re-rendering 되는 것은 아니다. 즉 shouldComponentUpdate()
의 리턴값에 따라 re-rendering 여부가 결정된다.
component.forceUpdate(callback)
render()
함수가 동작 되어야 하는 경우가 있을 수 있다. 이런 경우, React의 기본적인 component life cycle와 무관하기 때문에, 직접 React에게 해당 component가 re-rendering되야 한다고 알려야 한다. 이때 사용가능한 함수가 forceUpdate()
이다.forceUpdate()
을 호출하면 곧바로 render()가 호출된다. 즉 shouldComponentUpdate()
는 건너뛴다. 해당 메소드를 건너 뛰더라도, child components의 life cycle method는 정상적으로 다 호출된다. (즉 child component의 shouldComponentUpdate()
는 호출된다.), 그렇다 하더라도, React는 DOM의 변경을 잘 찾아서 변경된 부분만 update해준다.forceUpdate()
의 사용을 최대한 피하고, this.props 와 this.state로 처리하도록 권고 하고 있다.함수형 컴포넌트에서 state 사용 방법은 Hook 사용 편에서 자세히 설명하겠습니다.