본문 바로가기
프론트엔드/React

LifeCycle Method

by alswlfl 2022. 12. 2.

생명주기 메서드

컴포넌트가 브라우저 상에 나타나고, 업데이트되고, 사라지게 될 때 호출되는 메서드들 (+ 에러발생 시 호출되는 메서드도 존재)

  • 클래스형 컴포넌트에서만 사용 가능

React Lifecycle Methods diagram

 

React Lifecycle Methods diagram

Fully interactive and accessible React Lifecycle Methods diagram.

projects.wojtekmaj.pl

마운트될 때 발생하는 생명주기 메서드

1. constructor

  • 컴포넌트의 생성자 메서드
  • 컴포넌트가 만들어지면 가장 먼저 실행되는 메서드
constructor(props){
	super(props);
	console.log("constructor");
}

2. getDerivedStateFromProps

  • props로 받아온 것을 state에 넣어주고 싶을 때 사용
  • 앞에 static 필요, 안에 this를 조회 할 수 없음
  • 특정 객체를 반환하게 되면 해당 객체 안에 있는 내용들이 컴포넌트의 state로 설정됨, null을 반환하게 되면 아무 일도 발생 안함
  • 이 메서드는 처음 렌더링 되기 전에도 호출되고, 그 이후 렌더링 되기 전에도 매번 실행
static getDerivedStateFromProps(nextProps, preState){
	console.log("getDerivedStateFromProps");
	if (nextProps.color !== preState.color){
		return {color: nextProps.color };
	}
	return null;
}

3. render

  • 컴포넌트를 렌더링하는 메서드

4. componentDidMount

  • 컴포넌트의 첫 번째 렌더링이 마치고 나면 호출되는 메서드
  • 이 메서드가 호출되는 시점에는 만든 컴포넌트가 화면에 나타난 상태임
  • DOM을 사용해야하는 외부 라이브러리 연동하거나, 해당 컴포넌트에서 필요로 하는 데이터를 요하기 위해 axios 등 이용

업데이트 될 때 호출되는 생명주기 메서드

1. getDerivedStateFromProps

  • 처음 렌더링 되기 전에도 호출되고, 컴포넌트의 props나 state가 바뀌었을 때도 호출

2. shouldComponentUpdate

  • 컴포넌트가 리렌더링 할지 말지 결정하는 메서드
  • 주로 최적화 할 때 사용하는 메서드
shouldComponentUpdate(nextProps, nextState){
	console.log("shouldComponentUpdate", nextProps, nextState);
	//숫자의 마지막 자리가 4면 리렌더링하지 않음
	return nextState.number % 10 !== 4;
}

3. render

  • 컴포넌트를 렌더링하는 메서드

4. getSnapshotBeforeUpdate

  • 컴포넌트에 변화가 일어나기 직전의 DOM 상태를 가져와서 특정 값을 반환
getSnapshotBeforeUpdate(prevProps, prevState){
	console.log("getSnapshotBeforeUpdate");
	if(prevProps.color !== this.props.color){
		return this.myRef.style.color;
	}
	return null;
}

5. componentDidUpdate

  • 리렌더링이 마치고, 화면에 우리가 원하는 변화가 모두 반영되고 난 뒤 호출되는 메서드
  • DOM에 변화가 반영되기 직전에 DOM의 속성을 확인하고 싶을 때 사용
componentDidUpdate(prevProps, prevState, snapshot){
	console.log("componentDidUpdate", prevProps, prevState);
	if(snapshot){
		console.log("업데이트 되기 직전 색상: ",snapshot);
	}
}

언마운트될 때 호출되는 생명주기 메서드

1. componentWillUnmout

  • 컴포넌트가 화면에서 사라지기 직전에 호출
componentWillUnmount(){
	console.log("componentWillUnmout");
}
  • DOM에 직접 등록했었던 이벤트를 제거하고, 만약에 setTimeout을 걸은 것이 있으면 clearTimeout을 통해 제거
  • 외부 라이브러리를 사용했거나, 해당 라이브러리에 dispose기능이 있으면 componentWillUnmount에서 호출

에러 발생시 호출되는 생명주기 메서드, componentDidCatch

  • 리액트 애플리케이션에서 발생하는 에러를 처리하는 방법

리액트 앱에서 에러가 발생하는 상황

1. props를 제대로 설정하지 않은 경우

import React from "react";

function User({ user }) {
  return (
    <div>
      <div>
        <b>ID</b>: {user.id}
      </div>
      <div>
        <b>Username:</b> {user.username}
      </div>
    </div>
  );
}

export default User;
import React from "react";
import User from "./User";

function App() {
  const user = {
    id: 1,
    useranme: "velopert",
  };
  return <User />;
}

export default App;

[해결 방법]: 값이 존재하지 않는다면 null을 렌더링 하게 하기(null checking)

import React from "react";

function User({ user }) {
  if (!user) {
    return null;
  }
  return (
    <div>
      <div>
        <b>ID</b>: {user.id}
      </div>
      <div>
        <b>Username:</b> {user.username}
      </div>
    </div>
  );
}

export default User;

2. 값 설정을 해주지 않은 경우

function Users({users}){
	return(
		<ul>
			{users.map(user => (
				<li key={user.id}>{user.username}</li>
			))}
	);
}

[해결 방법]: users 가 없으면 다른 결과물을 반환하는 작업

function Users({ users }) {
  if (!users) return null;

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.username}</li>
      ))}
    </ul>
  );
}

3. props 전달하지 않은 경우

function Users({ users, onToggle }) {
  if (!users) return null;

  return (
    <ul>
      {users.map(user => (
        <li key={user.id} onClick={() => onToggle(user.id)}>
          {user.username}
        </li>
      ))}
    </ul>
  );
}

[해결 방법]: props로 넣어주는 것을 까먹지 않기 위해 defaultProps 설정

Users.defaultProps = {
  onToggle: () => {
    console.warn('onToggle is missing!');
  }
};

componentDidCatch로 에러 잡아내기

: 사전에 예외처리를 하지 않은 에러가 발생 했을 때 사용자에게 에러가 발생했다고 알려주는 화면을 보여줌

import React, { Component } from "react";

class ErrorBoundary extends Component {
  state = {
    error: false,
  };
  componentDidCatch(error, info) {
    console.log("에러가 발생했습니다.");
    console.log({
      error,
      info,
    });
    this.setState({
      error: true,
    });
  }
  render() {
    if (this.state.error) {
      return <h1>에러 발생!</h1>;
    }
    return this.props.children;
  }
}
export default ErrorBoundary;
  • componentDidCatch 메서드의 첫 번째 파라미터는 에러의 내용, 두 번째 파라미터는 에러가 발생한 위치
  • this.state.error값이 true이면 에러가 발생했다는 문구 렌더링, 그렇지 않으면 this.props.children을 렌더링하도록 처리
  • 그 후, App 컴포넌트에서 <User />컴포넌트 감싸줌
return(
	<ErrorBoundary>
		<User />
	</ErrorBoundary>
);

Sentry 연동

: 개발자가 발견해내지 못했지만, 사용자가 발견하게 되는 오류가 있을 시에, componentDidCatch에서 error와 info값을 네트워크를 통해 다른 곳으로 전달 해줌 → Sentry 상용서비스

https://sentry.io/auth/login/

 

Sign In | Sentry

 

sentry.io

 

'프론트엔드 > React' 카테고리의 다른 글

Sass  (0) 2022.12.06
리액트 개발 시 사용하면 편리한 도구  (0) 2022.12.02
클래스형 컴포넌트  (0) 2022.12.02
Immer  (0) 2022.11.24
Context API  (0) 2022.11.24