React Life Cycle이란? (react life cycle method와 hooks!)

이예슬·2022년 7월 24일
2

스터디

목록 보기
6/10

마지막 프로젝트 팀원들과 함께 프론트엔드 스터디를 시작했다!
프로젝트를 진행하면서 프론트엔드 기본지식이 조금 부족하다고 생각이 들었고 비슷한 생각을 한 팀원들과 함께 프론트엔드 스터디를 시작했다!

첫번째 주제는 React Life Cycle로 내가 제안한 주제였다. 이번 프로젝트를 진행하면서 class component를 function component로 리팩토링을 한 적이 있었는데 그 과정에서 react life cycle에 대해 좀 더 공부하고 싶다는 생각이 들었었다.


React Life Cycle이란?

모든 리액트 컴포넌트는 생명주기가 존재한다.
컴포넌트는 생성(Mounting) -> 업데이트(Updating) -> 제거(Unmounting)의 생명주기를 가지며 클래스 컴포넌트는 라이프 사이클 메서드를 활용하고 함수 컴포넌트는 Hook을 사용한다.

React Life Cycle을 알아야 하는 이유!

💡 생명주기를 알고 생명주기에 따라 어떤 작업을 처리해줘야 하는지 지정해줘야 불필요한 리렌더링을 방지할 수 있다.

React Life Cycle methods diagram


React Life Cycle method

마운트

컴포넌트의 인스턴스가 생성되어 DOM 상에 삽입될 때에 순서대로 호출된다.

  • constructor
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()

1. constructor

react 컴포넌트의 constructor는 해당 컴포넌트가 마운트되기 전에 호출된다.

constructor는 보통 아래 두 가지 목적을 위해 사용된다.

  • this.state에 객체를 할당하여 지역 state를 초기화
  • 인스턴스에 이벤트 처리 메서드를 바인딩
constructor(props) {
  super(props);
  // 여기서 this.setState()를 호출하면 안 됩니다!
  this.state = { counter: 0 };
  this.handleClick = this.handleClick.bind(this);
}

2. getDerivedStateFromProps

getDerivedStateFromProps는 props로 받아온 것을 state에 넣어주고 싶을 때 사용한다.

static getDerivedStateFromProps(nextProps, prevState) {
    console.log("getDerivedStateFromProps");
    if (nextProps.color !== prevState.color) {
      return { color: nextProps.color };
    }
    return null;
  }

다른 생명주기 메서드와는 달리 앞에 static 을 필요로 하고, 이 안에서는 this 를 조회 할 수 없다. 여기서 특정 객체를 반환하게 되면 해당 객체 안에 있는 내용들이 컴포넌트의 state 로 설정이 되고 반면 null 을 반환하게 되면 아무 일도 발생하지 않는다.

참고로 이 메서드는 컴포넌트가 처음 렌더링 되기 전에도 호출 되고, 그 이후 리렌더링 되기 전에도 매번 실행된다.

3. render()

UI를 렌더링 하는 메소드

→ 함수 컴포넌트로 치면 그 자체!

4. componentDidMount()

componentDidMount()

컴포넌트가 마운트된 직후 즉 트리에 삽입된 직후에 호출된다. DOM 노드가 있어야 하는 초기화 작업은 이 메서드에서 이루어지면 되며 라이브러리나 프레임워크의 함수를 호출하거나 이벤트 등록, setTimeout, setInterval과 같은 비동기 작업을 처리하면 되고, setState 호출도 이 메서드에서 호출하는 경우가 많다.

업데이트

업데이트가 일어나는 상황

  1. props가 바뀔 때
  2. state가 바뀔 때
  3. 부모 컴포넌트가 리렌더링 될 때
  4. this.forceUpdate로 강제로 렌더링을 트리거 할 때

위와 같이 업데이트가 일어나는 상황에서 아래 메서드들이 순서대로 호출된다.

  • static getDerivedStateFromProps()
  • shoudComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate

1. getDerivedStateFromProps

마운트 때 일어나는 메소드와 동일한 메소드이다!

2. shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState)

컴포넌트가 리렌더링 할지 말지를 결정하는 메서드로 주로 최적화할 때 사용하는 메서드이며 useMemo와 비슷한 역할을 한다.

3. render()

4. getSnapshotBeforUpdate()

getSnapshotBeforeUpdate는 컴포넌트에 변화가 일어나기 직전의 DOM 상태를 가져와서 특정 값을 반환하면 그 다음 발생하게 되는 componentDidUpdate함수에서 받아와서 사용을 할 수 있다.

getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log("getSnapshotBeforeUpdate");
    if (prevProps.color !== this.props.color) {
      return this.myRef.style.color;
    }
    return null;
  }

5. componentDidUpdate()

componentDidUpdate(prevProps, prevState, snapshot)

컴포넌트 업데이트 작업이 끝난 직후 호출하는 메서드
리렌더링이 마치고 화면에 우리가 원하는 변화가 모두 반영되고 난 뒤 호출되는 메서드로 3번째 파라미터로 getSnapshotBeforUpdate에서 반환한 값을 조회할 수 있다.
컴포넌트가 갱신되었을 때 DOM을 조작하기 위해서 이 메서드를 활용하면 좋으며 이전과 현재의 props를 비교하여 네트워크 요청을 보내는 작업도 이 메서드에서 이루어지면 된다.

언마운트

컴포넌트를 제거하는 과정, 아래 메서드는 컴포넌트가 DOM 상에서 제거될 때 호출된다.

componentWillUnmount()

componentWillUnmount()

컴포넌트가 마운트 해제되어 제거되기 직전에 호출된다.
이 메서드 내에서 주로 DOM에 직접 등록했었던 이벤트를 제거하고, 만약에 setTimeout을 걸은것이 있다면 clearTimeout을 통하여 제거한다.
컴포넌트는 다시 렌더링되지 않으므로 componentWillUnmount() 내에서 setState()를 호출하면 안된다.
컴포넌트 인스턴스가 마운트 해제되고 나면 절대로 다시 마운트되지 않는다.

React Hook!

Hook이란?

→ 함수 컴포넌트에서 react state와 라이프 사이클 기능을 연동할 수 있게 해주는 함수이다. hook은 class 안에서는 동작하지 않으며 대신 class 없이 React를 사용할 수 있게 해주는 것이다.

React Hook 도입 배경

  • 컴포넌트 사이에서 상태 로직을 재사용하기 어렵다
  • 복잡한 컴포넌트들은 이해하기 어렵다.
  • hook을 통해 class 없이 react 기능들을 사용할 수 있다.

→ class component의 단점들을 극복하기 위해 function component + hook이 도입된 것 같다.

사용 규칙

  • 최상위에서만 Hook을 호출해야 한다. 반복문, 조건문, 중첩된 함수 내에서 Hook을 실행할 수 없다.
  • 함수 컴포넌트에서만 Hook을 호출할 수 있다.

리팩토링 할 때도 느꼈는데 처음에 function component + hook으로 배워서 그런지 나는 class component보다 function component + hook이 훨씬 사용하기에 편하다는 생각이 들었다.

useEffect

  • Effect Hook을 사용하면 함수 컴포넌트에서 side effect를 실행할 수 있다.
  • useEffect는 컴포넌트가 mount, update, unmount 됐을 때의 작업을 처리할 수 있다.
  • useEffect는 기본적으로 componentDidMount, componentDidUpdate, componentWillUnmount, getDerivedStateFromProps의 역할을 모두 한다.

기본 형태

useEffect(callBackFunc);
  • useEffect는 기본적으로 componentDidMount(), componentDidUpdate(), componentWillUnmount(), getDerivedStateFromProps()의 역할을 모두 한다.
  • 때문에 위 코드는 1) 컴포넌트가 마운트 된 후, 2) 컴포넌트가 업데이트되고 난 후 3) 컴포넌트가 언마운트 되기 전 모두 실행됩니다.
useEffect(callBackFunc, []);
  • 컴포넌트가 최초 렌더링 되었을 때만 실행된다.
  • componentDidMount 역할을 수행한다.
useEffect(callBackFunc, [state1, state2]);
  • 최초 렌더링 + state1 or state2가 변경되었을 때 실행된다
  • componentDidUpdate, getDerivedStateFromProps의 역할을 수행한다.

clean-up을 이용하는 effects

외부 데이터에 구독(subscription)을 설정해야 하는 경우, 이런 경우에 메모리 누수가 발생하지 않도록 정리(clean-up)해야 한다.

useEffect(()=>{ return(() => func()) });
  • useEffect는 clean-up 함수를 return 할 수 있는데 clean-up 함수를 활용하여 컴포넌트가 unmount될 때 정리해야할 것들을 처리할 수 있다.
  • componentWillUnmount의 역할을 수행한다.

profile
꾸준히 열심히!

0개의 댓글