Hooks 도입 이후, 과거 Class 컴포넌트에서만 가능하던 상태 시스템, 라이프사이클 메소드가 Functional 컴포넌트에서도 구현이 가능해졌다. 하지만 많은 레거시 코드들이 Class 컴포넌트로 작성되어 있음을 생각해보면, Class 컴포넌트와 Functional 컴포넌트를 둘 다 이해할 수 있어야 한다.
아래 functional 컴포넌트로 작성된 코드에서 실행 순서는 다음과 같다.
1) JS 파일이 브라우저에 의해 실행된다.
2) App component 가 생성된다.
3) geolocation service 를 호출한다.
4) App 이 JSX 를 반환하고, HTML로 렌더링된다.
5) (잠시 후) geolocation 정보를 얻는다.
const App = () => {
window.navigator.geolocation.getCurrentPosition(
(position) => console.log(position),
(err) => console.log(err)
);
return <div>Hi there</div>;
};
위의 코드를 라이프사이클 메소드를 통해 핸들링해보자.
아래 코드는 Class 컴포넌트로 리팩토링 후 변화된 실행 순서이다.
1) JS 파일이 브라우저에 의해 실행된다.
2) App component 의 인스턴스가 생성되고, 가장 먼저 constructor 함수가 실행된다.
3) State 객체가 생성되고, this.state 에 할당된다.
4) render method 가 실행된다.
5) App 이 JSX 를 반환하고, HTML로 렌더링된다.
6) componentDidMount가 실행되고, geolocation service 를 호출한다.
7) geolocation 정보를 얻은 후, this.setState 를 통해 업데이트된다.
8) render method 가 다시 실행된다.
9) update 된 정보를 담아 JSX가 반환된다.
class App extends React.Component {
constructor(props) {
super(props);
this.state = { lat: null };
}
componentDidMount() {
window.navigator.geolocation.getCurrentPosition(
(position) => this.setState({ lat: position.coords.latitude }),
(err) => console.log(err)
);
}
render() {
return <div>Latitude: {this.state.lat}</div>;
}
}
constructor()
render()
스크린에 내용이 나타남componentDidMount()
render() 실행 후 한 번 실행됨componentDidUpdate()
state 업데이트때마다, render() 재실행후 실행됨componentWillUnmount()
컴포넌트가 화면에서 사라질 때 실행됨constructor
state 초기화 등 one-time setup render
자주 실행되므로, JSX 반환 외에 별도의 작업 (api request 등)은 하지 않는 것이 좋음componentDidMount
초기 데이터 로딩componentDidUpdate
상태값/props 변화에 따른 추가 데이터 로딩componentWillUnmount
cleanup 이 필요할 때consturctor 를 생략해도 된다. 왜냐하면 babel 이 constructor 를 생성하기 때문에, babel 이 컴파일링한 후에는 결과값이 동일하다. 따라서, 아래의 두 코드 역시 동일하게 작동한다.
// with constructor
class App extends React.Component {
constructor(props) {
super(props);
this.state = { message: 'hello world' };
}
render() {
return <div>Hello world</div>
}
}
// without constructor
class App extends React.Component {
state = { message: 'hello world' };
render() {
return <div>Hello world</div>
}
}
예컨대, SeasonDisplay.js 안에서 아래와 같이 CSS 파일을 import 하면, Webpack 이 하나로 묶어내는 과정에서 CSS 파일을 발견하고 index.html 로 가져다 붙인다.
import './SeasonDisplay.css';
import React from 'react';