들어가며
라이프사이클 메서드는 클래스형 컴포넌트에서만 사용이 가능한데,리액트 v16.8 이후부터는 함수형 컴포넌트에서 hooks 개념이 도입되면서 라이프 사이클과 같은 작업을 처리할 수 있다. 그럼에도 불구하고 클래스형 컴포넌트에선 어떠한 라이프사이클 메소드가 있고 어떻게 사용하는지 알고 넘어가야 할 것 같아서 정리한다. 그리고 혹시나 회사의 레거시 코드가 클래스형 컴포넌트로 작성되어 있을 수도 있으니까 대비할겸..?
라이프사이클
리액트는 컴포넌트 기반의 view만을 신경쓰는, view 중심 라이브러리이기 때문에 각각의 컴포넌트에는 생명주기, 라이프사이클이 존재한다. 컴포넌트의 생명주기는 렌더링 되기 전 준비과정(mount)에서 시작해 페이지에서 사라질 때(unmount) 끝이난다.
마운트(mount)
1. constructor
constructor는 컴포넌트의 생성자 메서드 컴포넌트가 만들어지면 가장 먼저 실행되는 메서드이다. 이 메서드에서는 초기 state를 지정할 수 있다.
생성자는 아래의 두가지 목적을 위해 사용된다.
- this.state에 객체를 할당하여 로컬 state 추가하기
- 인스턴스에 이벤트 처리 메서드를 바인딩
class Example extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
// 이벤트 핸들러 콜백에서 this가 작동하려면 아래처럼 바인딩 해줘야 한다!
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
/*
this.handleClick을 바인딩하지 않고 onClick에 전달하였다면, 함수가 실제 호출될 때 this는 undefined가 된다.
일반적으로 onClick={this.handleClick}과 같이 뒤에
()를 사용하지 않고 메서드를 참조할 경우, 해당 메서드를 바인딩 해야 한다.
*/
2. getDerivedStateFromProps
이 메서드는 리액트 16.3버전 이후에 생긴 메서드이다. getDerivedStateFromProps 는 props 로 받아온 것을 state 에 넣어주고 싶을 때 사용하며, 컴포넌트가 마운트될 때와 업데이트될 때 호출된다. state값을 변경하고 싶으면 setState를 사용하는 것이 아닌 return을 사용한다. null을 반환하게 되면 아무일도 발생하지 않는다. 다른 생명주기 메서드와는 달리 앞에 static 을 필요로 하고, 이 안에서는 this를 조회 할 수 없다.
class Example extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.value !== prevState.value) {
return { value: nextProps.value }
}
return null
}
}
3. render
render메서드는 클래스 컴포넌트에서 반드시 구현돼야하는 유일한 메서드이다. 이 메서드에서는 컴포넌트의 state를 변경하는 side effect가 발생해서는 안되고 호출될 때 마다 동일한 결과를 반환하는 순수함수여야 한다.
class Example extends React.Component {
render() {
return <div>...</div>
}
}
4. componentDidMount()
컴포넌트가 DOM 트리에 삽입된 직후에 호출된다. DOM과 상호작용 하거나 외부에서 데이터를 불러와야 한다면 네트워크 요청을 위한 코드를 이 메서드에서 작성하면 된다.
class Example extends React.Component {
componentDidMount() {
...
}
}
업데이트(update)
1. getDerivedStateFromProps
mount 단계와 동일하다.
2. shouldComponentUpdate
현재 state 또는 props를 변경했을 때 컴포넌트가 리렌더링을 할지 말지 여부를 결정하는 메서드이다. return타입으로 true, false을 주어야하며 결과에 따라 DOM 리렌더링 여부를 결정한다. 이 메서드는 오직 성능 최적화만을 위한 것. (렌더링 방지 목적으로 사용할 경우 버그가 발생 할 수 있다고 한다.)
class Example extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return nextProps.value !== this.props.value
}
}
리액트 공식문서에서는 shouldComponentUpdate()의 내용을 직접 작성하는 대신에 PureComponent를 사용하는 것을 권장한다.
PureComponent에 대해서는 다음에 자세히 알아보자
3. render
mount 단계와 동일하다.
4. getSnapshotBeforeUpdate
render에서 만들어진 결과가 브라우저에 실제로 반영되기 직전에 호출된다. 이 메서드를 사용하면 컴포넌트가 DOM으로부터 스크롤 위치 등과 같은 정보를 변경되기 전에 얻을 수 있다. 이 메서드가 반환한 값은componentDidUpdate에 인자로 전달된다.
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
}
}
// scrollTop - 스크롤된 y 좌표값
// scrollHeight - 해당 엘리먼트의 높이
5. componentDidUpdate
리렌더링을 마치고, 화면에 우리가 원하는 변화가 모두 반영되고 난 뒤 호출되는 메서드. 컴포넌트가 갱신되었을 때 DOM을 조작하기 위하여 이 메서드를 활용하면 좋다. 이전과 현재의 props를 비교하여 네트워크 요청을 보내는 작업을 해당 메서드에서 하면된다. 3번째 파라미터로 getSnapshotBeforeUpdate 에서 반환한 값을 조회 할 수 있다.
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("componentDidUpdate", prevProps, prevState);
if (snapshot) {
console.log("snapshot", snapshot);
}
}
언마운트(unmount)
1. componentWillUnmount
componentWillUnmount 는 컴포넌트가 화면에서 사라지기 직전에 호출된다. componentDidMount 에서 등록한 이벤트가 있다면 이 메서드에서 제거한다.
class Example extends React.Component {
coomponentWillUnmount() {
...
}
}
'Programming > React' 카테고리의 다른 글
배열 key props (0) | 2023.04.28 |
---|---|
useState의 렌더링, 함수형 업데이트 (0) | 2023.04.28 |
React 클래스 컴포넌트 이벤트 처리와 this (0) | 2021.09.22 |
React PureComponent를 알아보자! (0) | 2021.09.19 |
React portal에 대해 알아보자! (0) | 2021.09.17 |