記錄

[React Study - 5] Life cycle, useEffect() 본문

FRONTEND STUDY/React

[React Study - 5] Life cycle, useEffect()

prts 2022. 12. 11. 22:26

00 Lifecycle 생명주기

Life cycle 관련 공식문서: https://ko.reactjs.org/docs/state-and-lifecycle.html

 

생명주기는 컴포넌트가 브라우저 상에 나타나고(componentDidMount), 업데이트되고(componentDidUpdate), 사라지게 될 때(componentWillUnmount) 호출되는 메소드들이다. 클래스형 컴포넌트에서만 사용 가능하다.

 

아래는 생명주기를 설명한 다이어그램이다.

https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

01 Life cycle의 3단계

마운트 Mount

마운팅 Mounting이란 DOM에 요소를 붙이는 것, 즉 DOM이 처음으로 렌더링될 떄를 말한다.

컴포넌트가 마운팅될 때 React는 아래와 같은 내장 메소드들을 순서대로 호출한다.

 

constructor

constructor()는 컴포넌트의 생성자 메서드로, 컴포넌트가 초기화될 때(=만들어질 때) 가장 먼저 실행되는 메서드이다.

state와 다른 초기값들을 세팅하며, props라고도 불린다.

constructor(props) {
    super(props); 
    console.log("constructor");
  }

constructor은 super(props)를 가장 먼저 호출해야 하며, 부모의 constructor 메서드 초기화 및 부모로부터 상속받은 메소드들을 컴포넌트로 하여금 사용할 수 있게 한다.

 

getDerivedStateFromProps

getDerivedStateFromProps() 는 DOM에서 요소들이 렌더링되기 직전에 호출되며, props 로 받아온 것을 state 에 넣어주고 싶을 때 사용한다.

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

다른 생명주기 메서드와 달리 static을 필요로 하며, 이 안에서는 this를 조회할 수 없다. 최초의 props에 기반한 state 객체를 저장하며, state를 인자로 받고 state 변경 시 객체를 반환한다. null을 반환 시에는 아무 일도 발생하지 않는다.

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

 

render

render()은 말 그대로 컴포넌트를 렌더링하는 메서드이다. DOM에 HTML을 표현해준다.

class Header extends React.Component {
  render() {
    return <h1>This is the content of the Header component</h1>
  }
}

ReactDOM.render(<Header />, document.getElementById('root'))

componentDidMount

componentDidMout() 메서드는 컴포넌트의 첫번째 렌더링이 마치고 나면 호출되는 메서드로, 이 시점에서 우리가 만든 컴포넌트가 화면에 나타난다. DOM에 위치한 컴포넌트를 필요로 하는 구문을 사용하는 곳이다.

DOM을 사용하는 외부 라이브러리 연동, 데이터를 요청하기 위해 ajax요청을 하는 등 DOM의 속성을 읽거나 직접 변경하는 작업을 진행한다.

class Header extends React.Component {
  constructor(props) {
    super(props)
    this.state = { favoritecolor: 'red' }
  }
  componentDidMount() {
    setTimeout(() => {
      this.setState({ favoritecolor: 'yellow' })
    }, 1000)
  }
  render() {
    return <h1>My Favorite Color is {this.state.favoritecolor}</h1>
  }
}

ReactDOM.render(<Header />, document.getElementById('root'))

 

업데이트 Update

컴포넌트가 업데이트가 되는 때를 의미한다. props, state가 변경될때마다 업데이트되며, 5가지의 내장 메서드가 컴포넌트 업데이트 시 순서대로 실행된다.

 

getDerivedStateFromProps

update 단계에서 getDerivedStateFromProps 메소드가 호출된다. 컴포넌트의 props 나 state 가 바뀌었을때도 이 메서드가 호출된다. 초기 props에 기반한 state 가 저장되는 곳이다.

 

shouldComponentUpdate

컴포넌트가 리렌더링 할지 말지를 결정하는 메서드로, 이에 대한 Boolean 값을 반환한다. 기본값은 true이다.

주로 최적화할 때 사용하는 메서드이다.

  shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate", nextProps, nextState);
    // 숫자의 마지막 자리가 4면 리렌더링하지 않습니다
    return nextState.number % 10 !== 4;
  }

render

변경점을 리렌더링한다.

 

getSnapshotBeforeUpdate

getSnapshotBeforeUpdate() 메서드는 업데이트 되기 전의 props와 state에 접근할 수 있다(=update이후에도 이전 값을 확인할 수 있음). 컴포넌트에 변화가 일어나기 직전의 DOM  상태를 가져와서 특정 값을 반환하면 그 다음 발생하게 되는 componentDidUpdate 함수에서 받아와서 사용할 수 있다.

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

componentDidUpdate

리렌더링 완료 후, 화면에 업데이트가 모두 반영된 이후 호출되는 메서드이다. 컴포넌트가 DOM에서 update된 후에 호출된다. 3번째 파라미터로 getSnapshotBeforeUpdate에서 반환한 값을 조회할 수 있다.

  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("componentDidUpdate", prevProps, prevState);
    if (snapshot) {
      console.log("업데이트 되기 직전 색상: ", snapshot);
    }
  }

 

언마운트  Unmount

컴포넌트가 DOM을 제거하거나 Unmounting 할 때를 의미하고, 관련된 메서드는 componentWillUnmount 하나이다.

 

componentWillUnmount

컴포넌트가 화면에서 사라지기 직전, 즉 DOM에서 컴포넌트가 제거될 때 호출되는 메서드이다.

주로 DOM에 직접 등록했었던 이벤트를 제거한다.

  componentWillUnmount() {
    console.log("componentWillUnmount");
  }

현재는 비교적 최근에 등장한 함수형 컴포넌트를 더 많이 사용하기 때문에 후술할 useEffect()를 더 많이 사용하게 될 것이다.

02 useEffect()

useEffect Hook 공식문서: https://ko.reactjs.org/docs/hooks-effect.html

* Hook

 

Hook 이전, React 16.8 버전 이전의 컴포넌트는 다음과 같았다.

Function Component Class Component
state 사용 불가 생성자에서 state 정의
Lifecycle 에 따른 기능 구현 불가 setState() 함수를 통해 state 업데이트
  Lifecycle 메서드 제공

Hook의 추가로 함수형 컴포넌트에서도 side effect를 사용할 수 있게 되면서 클래스형 컴포넌트에서만 사용 가능했던 생명주기 메서드를 대체할 수 있게 되었다.

 

* Side Effect: React 컴포넌트가 화면에 렌더링된 이후 비동기로 처리되어야 하는 부수적인 효과들(DOM 변경 등)
다른 컴포넌트에 영향을 미칠 수 있고, 렌더링 중에는 작업이 완료될 수 없음

 

마치 갈고리를 거는 것처럼 기능에 갈고리를 걸어 원하는 시점에 정해진 함수를 실행하기 때문에 이러한 함수들을 Hooks 라고 부른다. 직접 개발자가 커스텀 Hook을 만들어 사용할 수도 있다(반드시 이름 앞에 use를 붙어 hook임을 알려야 함).

 

React 16.8 버전 이후 추가된 Hooks 중 useEffect 라는 Hook을 활용하면 함수 컴포넌트에서 side effect를 수행할 수 있게 되었다.

 

즉, useEffect()는 state를 사용하기 위한 hook이라고 할 수 있다.

 

useEffect() 사용법

useEffect()를 사용하여 컴포넌트가 마운트 됐을 때 (처음 나타났을 때), 언마운트 됐을 때 (사라질 때), 그리고 업데이트 될 때 (특정 props가 바뀔 때) 처리할 수 있는 방법을 알아보자.

 

기본적인 useEffect의 형태는 다음과 같다.

useEffect(이펙트 함수, 의존성 배열)
useEffect(effect, [, deps]);

첫 번째 인자(effect)로는 함수, 두 번째 인자로는 배열(deps)가 들어간다.

effect 함수는 렌더링 이후 실행할 함수로, 리액트는 이 함수를 기억했다가 DOM 업데이트 후 불러낸다. effect함수에서 함수를 return 할 경우 그 함수가 컴포넌트가 Unmount 될 때 정리의 개념으로 한 번 실행된다.

 

의존성 배열이 비어 있으면 mount, unmount 시 단 한번씩만 실행된다.

useEffect(effect,[]);

의존성 배열을 생략하면 컴포넌트가 업데이트될 때마다 호출된다.

useEffect(effect);

아래의 코드는 componentDidMount, componentDidUpdate와 비슷하게 작동한다.

import React, {useState,useEffect} from 'react'

export default function App(){
  const [count,setCount]=useState(0);

  useEffect(()=>{
     document.title=`You clicked ${count} times`;
  });

  return (
    <div>
       <p> 총 {count} 번 클릭했습니다.</p>
       <button onClick={()=>setCount(count+1)}>
    </div>
  )
}

cleanUp 함수

useEffect 안에서 return 할 때 실행되는 함수로, useEffect의 뒷정리를 해준다. 컴포넌트가 마운트될 때 이벤트 리스너를 통해 이벤트를 추가했다면 컴포넌트가 언마운트될 때 이벤트를 삭제해줘야 하기 때문에(리렌더링 시 새로운 이벤트 리스너가 핸들러에 바인딩될 것이기 때문) 필요한 함수이다.

생명주기 메서드에 비유하자면 componentWillUnmount의 역할을 한다고 볼 수 있다.

import React, {useState,useEffect} from 'react'

export default function App(){
  const [state,setState]=useState(initialState)

  useEffect(()=>{
     return () => {
        cleanup //언마운트될 때 리턴된 함수를 실행(정리해야 하는 내용을 넣음)
     }
  }, [state,props.a]) //의존성 배열 array dependencies

  return (
    <div>App</div>
  )
}

참고자료

 

React 공식 문서

https://react.vlpt.us/basic/25-lifecycle.html

https://serzhul.io/REACT/react-life-cycle(%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%83%9D%EB%AA%85-%EC%A3%BC%EA%B8%B0)/

https://goddaehee.tistory.com/308

처음 만난 리액트(React) Hooks의 개념과 useState, useEffect

 

 

'FRONTEND STUDY > React' 카테고리의 다른 글

[React 스터디 - 6] 리액트 CSS 적용 방법  (0) 2022.12.25
[React 스터디-5] List, Key  (0) 2022.12.18
[React 스터디 - 4] State  (0) 2022.12.04
[React Study - 3] Components, Props  (0) 2022.11.28
[React 스터디 - 1] React 란?  (0) 2022.11.13
Comments