이 포스팅은 React Document 주요개념 State와 생명주기 글을 보면서 React를 습득하면서 내용을 정리하기 위해 작성하는 포스팅입니다.
State에 대해 간단하게만 알아보고 자세한 State내용은 추후 포스팅하도록 하겠습니다.
React Document에서는 Clock을 갱신하는 소스코드는 컴포넌트를 만들때 그 안에 props로 date를 넣어줬었습니다.
function Clock(props) {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {props.date.toLocaleTimeString()}.</h2>
</div>
);
}
function tick() {
ReactDOM.render(
<Clock date={new Date()} />,
document.getElementById('root')
);
}
setInterval(tick, 1000);
사실 Clock 함수는 외부에서 타이머를 설정하는것이 아닌 Clock 자체에서 매초 UI를 업데이트 하도록 해야합니다.
이번 포스팅에서는 이러한 구현을 하기위해 state라는 것을 배워보도록 합니다
State는 전에 배웠던 Props와 같이 컴포넌트의 렌더링 결과물에 영향을 주는 데이터 객체이지만, props와 다르게 state는 컴포넌트 안에서 관리되는 상태를 의미한다. ( 캡슐화
를 통해 사용자가 알필요 없는 데이터는 내부에 은닉하는것이 좋다 )
그렇다면 위에 있던 Clock 함수를 state를 통해 변경해 보도록 하겠습니다. Hooks를 들어가기 전이라 이번 예제는 class Component를 이용하여 구현해보도록 하겠습니다.
// import 등은 생략하겠습니다.
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
setInterval(tick, 1000);
state를 사용하면서 주의해야할 내용이 있습니다.
일단 잘못된 코드와 제대로 작성된 코드먼저 보겠습니다
state를 변경하기 위해서는 setState나 함수형 컴포넌트의 useState를 이용하여 변경하여야 한다.
예제는 일반 변수를 예로 들었지만 , 배열이나 객체를 업데이트 하기 위해서는 객체 사본을 만들고 그 사본에 값을 업데이트 한 후 그 사본을 업데이트해줘야 한다.
// 나쁜 예
this.state.name = "YundleYundle";
// 좋은 예
this.setState({name:"YundleYundle"});
state는 비동기 방식으로 동작합니다. React를 처음 하면서 setState를 하다보면 가끔 내가 원하는 결과가 안나올때가 있었습니다. 찾아보니 React의 setState는 동기가 아닌 비동기로 처리된다는 내용이었습니다.
// 나쁜 예
// this.props와, this.state는 비동기적으로 업데이트가 될 수 있기때문에
// 업데이트시 내가 원하는 결과와 다른 값이 나올 수 있다.
this.setState({
counter: this.state.counter + this.props.increment,
});
정삭적으로 동작 시키기 위해서는 setState에서 callback 을 사용하는 방법입니다.
// 업데이트가 적용된 이후의 state와 props의 값을 가져온다.
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
React에서 컴포넌트를 만들어 진행하게 되면 부모 컴포넌트나 자식 컴포넌트 모두 특정 컴포넌트의 유/무상태에 대한 값을 알수가 없습니다. 그들이 함수나 클래스로 정의되었는지에 대해서는 관심을 가질 필요가 없다.
이러한 것때문에 state는 캡슐화라고 불리기도 한다. state가 소유하고 설정한 컴포넌트 외에는 어떠한 컴포넌트에도 접근할 수 없다.
// Clock 컴포넌트는 독립적이다라는것을 보여주기 위한 App 컴포넌트
function App() {
return (
<div>
<Clock />
<Clock />
<Clock />
</div>
);
}