React의 LifeCycle

Daisy·2022년 2월 23일

React

목록 보기
1/1
post-thumbnail

프론트엔드에서 흔히 사용되고 있는 AngularJS, Vue.js등의 프레임워크는 MVC, MVVM등의 디자인패턴을 가지고 만들어졌다. 가장 대표적인 MVC패턴Model, View, Controller 세 개의 컴포넌트로 이루어져있다.
각 컴포넌트는 다음과 같은 역할을 한다.

Model: 애플리케이션에서 사용하는 데이터 및 로직을 관리
View: 사용자에게 보여지는 레이아웃과 화면을 처리
Controller: 사용자의 입력, 조작에 따른 명령을 모델과 뷰 부분으로 라우팅

React는 Framework가 아닌 Library이다

그러나 MVC는 특성상 확장이 어렵고 애플리케이션의 규모가 커질 수록 데이터 흐름의 복잡도가 크게 증가한다.

따라서 React는 기존 MVC 패턴처럼 데이터가 변화할 때마다 어떻게 변화를 줄지 고민하는 것이 아닌, 데이터가 변할때마다 기존의 View를 날려버리고 새로 렌더링하는 방식을 고안했다.

React는 오로지 사용자의 View(V)에만 초점을 두고 만들어진 라이브러리이다.

Component

React는 UI를 구성하는 개별적인 view 단위 component를 사용한다.

각각의 component에는 라이프사이클, 즉 컴포넌트의 생명주기라는 것이 존재한다. 라이프사이클이란 컴포넌트가 페이지에 렌더링 되기 전 준비과정에서 시작해 페이지에서 사라질 때까지의 과정을 나타낸다.

라이프사이클은 크게 3가지 유형으로 나뉜다.

컴포넌트가 생성될 때, 업데이트될 때, 제거될 때 각각 Mount, Update, Unmount의 작업을 거치게 된다.

LifeCycle Method

Mount는 DOM이 생성되고 웹 브라우저 상에 나타나는 것을 뜻한다.

Update는 다음과 같이 크게 4가지 상황에서 발생한다.

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

Unmount는 DOM에서 제거되는 것을 뜻한다.

아래에서 하나씩 살펴보자.

Mount

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

  • constructor()
    constructor은 마운트 되기 이전에 컴포넌트를 만들 때 처음으로 실행된다.
    이 method에서 초기 state를 직접 할당할 수 있다.
// 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)
    props로 받아 온 값을 state에 동기화시키는 용도로 사용된다.
    컴포넌트가 마운트될 때와 업데이트 될 때 호출된다.
class Example extends React.Component {
  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.value !== prevState.value) {
      return { value: nextProps.value }
    }
    return null
  }
}
  • render()
    컴포넌트를 렌더링할 때 사용하는 필수 method이다.
    함수형 컴포넌트에서는 render()을 안쓰고도 컴포넌트를 렌더링할 수 있다.
// Class
class Example extends React.Component {
  render() {
    return <div>Component</div>
  }
}

// Hooks
const example = () => {
  return <div>Component</div>
}
  • componentDidMount()
    컴포넌트를 만들고 첫 렌더링을 마친 후 실행한다.
    함수형 Hooks에서는 useEffect를 활용하여 다음의 기능을 구현할 수 있다.
// Class
class Example extends React.Component {
    componentDidMount() {
        ...
    }
}

// Hooks
const Example = () => {
    useEffect(() => {
        ...
    }, []);
}

Update

props, state등이 변경되면 Update가 발생한다.
아래 method들은 컴포넌트가 리렌더링될 때 순서대로 호출된다.

  • static getDerivedStateFromProps(props, state)
  • shouldComponentUpdate(nextProps, nextState)
    현재 props나 state의 변화가 컴포넌트의 출력 결과에 영향을 미치는지 여부를 알 수 있다.
    반환값은 true, false 중 하나이며 이 반환값은 컴포넌트가 리렌더링을 할지 말지 결정한다.
    만약 false를 반환할 시에는 render(), componentDidUpdate()는 호출되지 않는다.
    주로 성능 최적화를 위해 사용하는 메서드이다.
// 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)
    가장 마지막으로 렌더링된 결과가 DOM에 반영되기 전에 호출된다. 이 method에서는 스크롤 위치 등 렌더링시에 변하는 정보들을 변겅되기 전에 얻을 수 있다.
    여기서 반환된 값은 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
  }
}
  • componentDidUpdate(prevProps, prevState, snapshot)
    컴포넌트가 업데이트 된 직후에 호출되며, 업데이트 되었을 때 DOM을 조작하기 위해 사용할 수 있다.
// Class
class Example extends React.Component {
    componentDidUpdate(prevProps, prevState) {
        ...
    }
}

// Hooks
const Example = () => {
    useEffect(() => {
        ...
    });
}

Unmount

아래 method는 컴포넌트가 DOM상에서 제거될 때 호출된다.

  • componentWillUnmount()
    컴포넌트의 마운트가 해제되어 제거되기 직전에 호출된다. componentDidMount()에서 등록한 이벤트를 제거할 수 있다.
    함수형 컴포넌트에서는 useEffect의 cleanUp 함수를 통해서 해당 메서드가 구현 가능하다.
// 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/

0개의 댓글