프론트엔드에서 흔히 사용되고 있는 AngularJS, Vue.js등의 프레임워크는 MVC, MVVM등의 디자인패턴을 가지고 만들어졌다. 가장 대표적인 MVC패턴은 Model, View, Controller 세 개의 컴포넌트로 이루어져있다.
각 컴포넌트는 다음과 같은 역할을 한다.
Model: 애플리케이션에서 사용하는 데이터 및 로직을 관리
View: 사용자에게 보여지는 레이아웃과 화면을 처리
Controller: 사용자의 입력, 조작에 따른 명령을 모델과 뷰 부분으로 라우팅
그러나 MVC는 특성상 확장이 어렵고 애플리케이션의 규모가 커질 수록 데이터 흐름의 복잡도가 크게 증가한다.
따라서 React는 기존 MVC 패턴처럼 데이터가 변화할 때마다 어떻게 변화를 줄지 고민하는 것이 아닌, 데이터가 변할때마다 기존의 View를 날려버리고 새로 렌더링하는 방식을 고안했다.
React는 오로지 사용자의 View(V)에만 초점을 두고 만들어진 라이브러리이다.
React는 UI를 구성하는 개별적인 view 단위 component를 사용한다.
각각의 component에는 라이프사이클, 즉 컴포넌트의 생명주기라는 것이 존재한다. 라이프사이클이란 컴포넌트가 페이지에 렌더링 되기 전 준비과정에서 시작해 페이지에서 사라질 때까지의 과정을 나타낸다.
라이프사이클은 크게 3가지 유형으로 나뉜다.
컴포넌트가 생성될 때, 업데이트될 때, 제거될 때 각각 Mount, Update, Unmount의 작업을 거치게 된다.
Mount는 DOM이 생성되고 웹 브라우저 상에 나타나는 것을 뜻한다.
Update는 다음과 같이 크게 4가지 상황에서 발생한다.
Unmount는 DOM에서 제거되는 것을 뜻한다.

아래에서 하나씩 살펴보자.
아래 method들은 컴포넌트의 인스턴스가 생성되어 DOM 상에 삽입될 때에 순서대로 호출된다.
constructor()// Class
class Example extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
// Hooks
const Example = () => {
const [count,setCount] = useState(0);
}
static getDerivedStateFromProps(props, state)class Example extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.value !== prevState.value) {
return { value: nextProps.value }
}
return null
}
}
render()// Class
class Example extends React.Component {
render() {
return <div>Component</div>
}
}
// Hooks
const example = () => {
return <div>Component</div>
}
componentDidMount()// Class
class Example extends React.Component {
componentDidMount() {
...
}
}
// Hooks
const Example = () => {
useEffect(() => {
...
}, []);
}
props, state등이 변경되면 Update가 발생한다.
아래 method들은 컴포넌트가 리렌더링될 때 순서대로 호출된다.
static getDerivedStateFromProps(props, state)shouldComponentUpdate(nextProps, nextState)// Class
class Example extends React.Component {
shouldComponentUpdate(nextProps) {
return nextProps.value !== this.props.value
}
}
// Hooks
const Example = React.memo(() => {
...
},
(prevProps, nextProps) => {
return nextProps.value === prevProps.value
}
)
렌더링을 방지하는 목적으로 사용하는 경우 버그로 이어질 수 있으며,
Class에서 불필요한 업데이트 작업을 건너뛰게 만들고 싶다면 PureComponent를 사용하는 것이 좋다.
Hook를 사용하고 있다면 React.memo, useMemo를 활용해 렌더링 성능을 개선할 수 있다.
render()getSnapshotBeforeUpdate(prevProps, prevState)class Example extends React.Component {
getSnapshotBeforeUpdate(prevProps, prevState) {
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current
return list.scrollHeight - list.scrollTop
}
return null
}
}
componentDidUpdate(prevProps, prevState, snapshot)// Class
class Example extends React.Component {
componentDidUpdate(prevProps, prevState) {
...
}
}
// Hooks
const Example = () => {
useEffect(() => {
...
});
}
아래 method는 컴포넌트가 DOM상에서 제거될 때 호출된다.
componentWillUnmount()// Class
class Example extends React.Component {
coomponentWillUnmount() {
...
}
}
// Hooks
const Example = () => {
useEffect(() => {
return () => {
...
}
}, []);
}
React 공식 문서
React Lifecycle Git Repo
https://salgum1114.github.io/reactjs/2019-11-28-react-class-equivalents/