render
, componentDidMount
, componentDidUpdate
, componentWillUnmount
등의 함수는 React.Component class에서 제공하는 메서드 입니다.
컴포넌트를 만들 때 class로 생성하면 위의 메서드를 사용할 수 있고, 컴포넌트가 lifecycle에 따라 각자의 메서드가 호출됩니다.
간단한 예제를 통해 컴포넌트를 만들고, lifecycle에 따라 state를 관리할 수 있도록 코드를 수정해보겠습니다.
아래의 코드는 1초에 한 번 tick함수를 호출해서 현재시간을 초 단위로 업데이트합니다.
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(
element,
document.getElementById('root')
);
}
setInterval(tick, 1000);
원래 코드에서 tick은 일반적인 함수이며, 내부에서 ReactDom.render를 호출해서 React 요소를 그려줍니다.
화면으로 보여줄 부분을 함수를 사용해서 컴포넌트로 만들어보겠습니다.
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);
최종적으로 이런형태가 되도록 만들어 보겠습니다.
(아래)
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
매초 업데이트 될 내용이 Clock 함수 내에서 이루어져야 하므로 class로 component를 만들어 봅시다.
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
props.date
를 this.props.date
로 바꿔줍니다.render 메서드는 ‘초’가 바뀔 때마다, 즉 1초마다 호출되어 내용을 변경해줘야 합니다.
그런데 Clock 컴포넌트(즉, Clock 인스턴스)는 mounting 동안은 본인 컴포넌트 내에서 값이 업데이트 되어야 하므로, state로 변경 값을 관리해야하고, lifecycle 메서드가 필요합니다.
Clock 컴포넌트에서 바뀌어야 하는 상태는 현재 시간입니다.
매 초마다 현재 시간을 새로 가져와야 하죠. props로 받던 date 정보를 state로 바꿔서 관리하겠습니다.
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
this.state로 바꾸어줬으니 초기 세팅이 필요합니다. constructor에서 합니다.
class Clock extends React.Component {
constructor() {
super();
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')
);
원래 tick 함수 외부에 있던 setInterval를 Clock 컴포넌트 내부로 들여와서, 매 초마다 새로운 시간을 가져오도록 수정해야합니다.
앞으로 프로그래밍을 할 때, 사용하던 리소스가 더 이상 필요없다면 없애주는 과정이 항상 필요합니다.
그래서 Clock 컴포넌트가 mounting 될 때 timer를 추가하고, 더 이상 화면에서 나올 필요 없는 unmounting이 되는 순간 timer를 삭제해주겠습니다.
class Clock extends React.Component {
constructor() {
super();
this.state = {date: new Date()};
}
componentDidMount() {
}
componentWillUnmount() {
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
Clock 컴포넌트가 화면에 그려지자마자 componentDidMount 메서드가 호출되면 timer를 시작하는 것입니다.
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
1초마다 tick 함수를 호출하게 됩니다.
tick 함수는 아마 새로운 날짜를 가져와서 this.state.date 에 업데이트해주는 함수일 것입니다.
생성한 timer는 this.timerId에 저장합니다.
setInterval 함수를 호출해서 timer를 생성하면, 해당 timer 의 id를 리턴하기 때문에 저장했습니다.
unmount 될 때, clearInterval 함수를 사용해서 아까 만들었던 timer를 삭제해줍니다.
componentWillUnmount() {
clearInterval(this.timerID);
}
이제 tick 함수를 구현할 차례입니다.
class Clock extends React.Component {
constructor() {
super();
this.state = {
date: new Date()
};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
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')
);
네 완성됐습니다! Clock 컴포넌트가 Mount 되고 -> Unmount 되기까지의 과정을 다시 한 번 훑어보겠습니다.
<Clock />
를 넘길 때, React는 Clock 컴포넌트의 constructor를 호출합니다.