React

[React] 리액트 라이프사이클 (React LifeCycle) 쉽게 이해하기

권군이 2021. 3. 5. 22:17

<리액트 라이프사이클>

 

React LifeCycle

 

리액트의 라이프 사이클 단계 

Mounting - Updating - Unmounting

 

Mount 단계 

: DOM에 올라갈 때

 

counstructor

 

: 컴포넌트가 브라우저에 나타나기 전에 호출되는 api

render()함수 전에 호출되는 라이프사이클 함수

컴포넌트 생성자 함수 , 컴포넌트가 새로 만들어질 때마다 이 함수가 호출됨.

 

constructor(props){
  super(props);
}

 

 

 

componentDidMount

 

: 컴포넌트가 브라우저에 나타나게 됐을 때 호출시

 

- DOM을 사용해야하는 외부라이브러리 연동시

- DOM의 속성을 읽거나 직접 변경하는 작업시

- 해당 컴포넌트에서 필요로하는 데이터를 요청하기 위해 axios,fetch 등을 통하여 ajax 요청시

 

componentDidMount(){
  //외부라이브러리 연동
  //ajax 요청
  //DOM 읽어오기,변경하기
}

 


Updating 단계

 

getDerivedStateFromProps

 

: props로 받아온 값을 state로 동기화 하는 작업을 해야하는 경우에 사용

 

getDerivedStateFromProps(nextProps, prevState){
  //여기에서는 setState를 하는 것이 아니라
  //특정 props가 바뀔 때 설정하고 
  //설정하고 싶은 state 값을 리턴하는 형태로 사용
}

 

 

shouldComponentUpdate

 

: 컴포넌트를 최적화하는 작업에 유용하게 사용

 

먼저, 현재 컴포넌트의 상태가 업데이트되지 않아도,

부모 컴포넌트가 리렌더링되면 자식 컴포넌트들도 렌더링 된다.

 

이 함수는 기본적으로 true를 반환하여 해당 컴포넌트의 render 함수를 호출한다.

false를 반환하면 호출하지 않는다. 이러한 방식으로 특정 컴포넌트가 리렌더링 될때 쓸데없이 낭비되고 있는 CPU 처리량을 줄여줄 수 있다. 즉, 컴포넌트를 최적화하는 것이다.

 

shouldComponentUpdate(nextProps, nextState){
  //return false 하면 업데이트를 안함

  return true;
}

 

getSnapshotBeforeUpdate

 

: render()함수 실행, 실제 DOM에 변화 발생하기 전에 호출

 

이 API가 발생하는 시점

1. render()

2. getSnapshotBeforeUpdate()

3. 실제 DOM에 변화 발생

4. componentDidUpdate

 

DOM 변화가 일어나기 직전의 DOM 상태를 가져오고,

여기서 리턴하는 값은 componentDidUpdate 에서 3번째 파라미터로 받아올 수 있게 됨.

 

getSnapshotBeforeUpdate(prevProps, prevState) {
  // DOM 업데이트가 일어나기 직전의 시점입니다.
  // 새 데이터가 상단에 추가되어도 스크롤바를 유지해보겠습니다.
  // scrollHeight 는 전 후를 비교해서 스크롤 위치를 설정하기 위함이고,
  // scrollTop 은, 이 기능이 크롬에 이미 구현이 되어있는데, 
  // 이미 구현이 되어있다면 처리하지 않도록 하기 위함입니다.
  if (prevState.array !== this.state.array) {
    const {
      scrollTop, scrollHeight
    } = this.list;
    // 여기서 반환 하는 값은 componentDidMount 에서 snapshot 값으로 받아올 수 있습니다.
    return {
      scrollTop, scrollHeight
    };
  }
}
componentDidUpdate(prevProps, prevState, snapshot) {
  if (snapshot) {
    const { scrollTop } = this.list;
    // 기능이 이미 구현되어있다면 처리하지 않습니다.
    if (scrollTop !== snapshot.scrollTop) return; 
    const diff = this.list.scrollHeight - snapshot.scrollHeight;
    this.list.scrollTop += diff;
  }
}

 

ComponentDidUpdate

 

: render()함수를 호출하고 난 다음에 발생

 

이 시점에서는 this.props 와 this.state 가 다른 값으로 업데이트 됨.

파라미터를 통해 이전값인 precvProps와 prevState를 조회할 수 있음.

snapshot으로 getSnapshotBeforeUpdated에서 반환되 값을 받아옴.

 

componentDidUpdate(prevProps, prevState, snapshot) {
  // DOM 변경 직후 실행할 내용
}

 


 

Unmounting 단계

 

componentWillUnmount

 

: 더 이상 컴포넌트를 사용하지 않게 될 때 호출

 

- 주로 등록했던 이벤트 제거

- setTimeout 걸은 것이 있다면 clearTimeout으로 제거

- 외부 라이브러리를 사용해 dispose 기능이 있다면 여기서 호출

 

 

componentWillUnmount() {
  // 이벤트, setTimeout, 외부 라이브러리 인스턴스 제거
}

 

 

Error 발생

 

componentDidCatch

 

:  render() 에서 에러가 발생할 때 사용

컴포넌트 자신의 render 함수에서 에러가 발생한 것은 잡아낼 수 없다.

컴포넌트의 자식 컴포넌트 내부에서 발생하는 에러들을 잡아냄.

 

ComponentDidCatch(error, info){
  this.setState({
    error: true
  });
}

 

(리액트라이프사이클 잘모르지만 이론만 정리해보았다)

 

 

참고

- taling-react-course.com/intro/lifecycle-api.html

- velog.io/@leo-xee/React-LifeCyle-API