๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
ํ”„๋ก ํŠธ์—”๋“œ/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