πŸ’» LifeCycle(feat. λ¦¬μ•‘νŠΈ κ³΅μ‹λ¬Έμ„œ)

waterglassesΒ·2022λ…„ 10μ›” 9일
1

TIL

λͺ©λ‘ 보기
41/50
post-thumbnail

⚠️ μ •λ¦¬ν•œ λ‚΄μš©μ€ μ˜€νƒ€λ‚˜ 잘λͺ»λœ 정보가 μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. λŒ“κΈ€λ‘œ μ•Œλ €μ£Όμ‹œλ©΄ κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€.

πŸ“ƒ LifeCycle

생λͺ…μ£ΌκΈ° λ©”μ„œλ“œλŠ” μ»΄ν¬λ„ŒνŠΈκ°€ λΈŒλΌμš°μ €μƒμ— λ‚˜νƒ€λ‚˜κ³ , μ—…λ°μ΄νŠΈ 되고, μ‚¬λΌμ§€κ²Œ 될 λ•Œ ν˜ΈμΆœν•˜λŠ” λ©”μ„œλ“œμ΄λ‹€. μΆ”κ°€μ μœΌλ‘œ μ»΄ν¬λ„ŒνŠΈμ—μ„œ μ—λŸ¬κ°€ 났을 λ•Œ ν˜ΈμΆœλ˜λŠ” λ©”μ„œλ“œλ„ μžˆλ‹€.

생λͺ…μ£ΌκΈ° λ©”μ„œλ“œλŠ” ν΄λž˜μŠ€ν˜• μ»΄ν¬λ„ŒνŠΈμ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆλ‹€.

좜처 http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

마운트

μ•„λž˜ λ©”μ„œλ“œλ“€μ€ μ»΄ν¬λ„ŒνŠΈμ˜ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜μ–΄ DOM 상에 μ‚½μž…λ  λ•Œμ— μˆœμ„œλŒ€λ‘œ ν˜ΈμΆœλ©λ‹ˆλ‹€.

constructor β†’ getDerivedStateFromProps β†’ render β†’ componentDidMount

constructor

constructor λŠ” μ»΄ν¬λ„ŒνŠΈμ˜ μƒμ„±μž λ©”μ„œλ“œμ΄λ‹€. μ»΄ν¬λ„ŒνŠΈκ°€ λ§Œλ“€μ–΄μ§€λ©΄ κ°€μž₯ λ¨Όμ € μ‹€ν–‰λ˜λŠ” λ©”μ„œλ“œμ΄λ‹€.

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

constructor()Β λ‚΄λΆ€μ—μ„œΒ setState()λ₯Ό ν˜ΈμΆœν•˜λ©΄ μ•ˆ λœλ‹€.

static getDerivedStateFromProps

getDerivedStateFromProps λŠ” props둜 λ°›μ•„μ˜¨ 것을 state에 λ„£μ–΄μ£Όκ³  싢을 λ•Œ μ‚¬μš©ν•œλ‹€. 이 λ©”μ„œλ“œλŠ” μ‹œκ°„μ΄ 흐름에 따라 λ³€ν•˜λŠ” props에 stateκ°€ μ˜μ‘΄ν•˜λŠ” μ•„μ£Ό λ“œλ¬Έ 사둀λ₯Ό μœ„ν•΄ μ‘΄μž¬ν•œλ‹€.

참고둜 μ»΄ν¬λ„ŒνŠΈκ°€ 처음 λ Œλ”λ§ 되기 전에도 호좜되고 κ·Έ 이후 λ¦¬λ Œλ”λ§ 되기 전에도 맀번 μ‹€ν–‰λœλ‹€.

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

render

μ»΄ν¬λ„ŒνŠΈλ₯Ό λ Œλ”λ§ν•˜λŠ” λ©”μ„œλ“œμ΄λ‹€.

componentDidMount

μ»΄ν¬λ„ŒνŠΈμ˜ 첫번째 λ Œλ”λ§μ΄ 마치고 λ‚˜λ©΄ ν˜ΈμΆœλ˜λŠ” λ©”μ„œλ“œμ΄λ‹€. 이 λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜λŠ” μ‹œμ μ—λŠ” μ»΄ν¬λ„ŒνŠΈκ°€ 화면에 λ‚˜νƒ€λ‚œ μƒνƒœμ΄λ‹€.

μ™ΈλΆ€μ—μ„œ 데이터λ₯Ό λΆˆλŸ¬μ™€μ•Ό ν•œλ‹€λ©΄, λ„€νŠΈμ›Œν¬ μš”μ²­μ„ 보내기 μ μ ˆν•œ μœ„μΉ˜λ‹€.

μ—…λ°μ΄νŠΈ

props λ˜λŠ” stateκ°€ λ³€κ²½λ˜λ©΄ 갱신이 λ°œμƒν•œλ‹€. μ•„λž˜ λ©”μ„œλ“œλ“€μ€ μ»΄ν¬λ„ŒνŠΈκ°€ λ‹€μ‹œ λ Œλ”λ§λ  λ•Œ μˆœμ„œλŒ€λ‘œ ν˜ΈμΆœλœλ‹€.

getDerivedStateFromProps β†’ shouldComponentUpdate β†’ render β†’ getSnapshotBeforeUpdate β†’ componentDidUpdate

getDerivedStateFromProps

마운트 될 λ•Œμ—λ„ μ„€λͺ…ν–ˆλ˜ λ©”μ„œλ“œ

shouldComponentUpdate

shouldComponentUpdate Β λ©”μ„œλ“œλŠ” μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λ Œλ”λ§ 할지 말지λ₯Ό κ²°μ •ν•˜λŠ” λ©”μ„œλ“œμ΄λ‹€. 주둜 μ΅œμ ν™” ν•  λ•Œ μ‚¬μš©ν•˜λŠ” λ©”μ„œλ“œμ΄λ©° React.memo 와 λΉ„μŠ·ν•˜λ‹€.

shouldComponentUpdate(nextProps, nextState) {
  console.log("shouldComponentUpdate", nextProps, nextState);
  // 숫자의 λ§ˆμ§€λ§‰ μžλ¦¬κ°€ 4λ©΄ λ¦¬λ Œλ”λ§ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€
  return nextState.number % 10 !== 4;
}

render

μ»΄ν¬λ„ŒνŠΈλ₯Ό λ Œλ”λ§ν•˜λŠ” λ©”μ„œλ“œ

getSnapshotBeforeUpdate

getSnapshotBeforeUpdate Β λŠ” μ»΄ν¬λ„ŒνŠΈμ— λ³€ν™”κ°€ μΌμ–΄λ‚˜κΈ° μ§μ „μ˜ DOM μƒνƒœλ₯Ό κ°€μ Έμ™€μ„œ νŠΉμ • 값을 λ°˜ν™˜ν•˜λ©΄ κ·Έ λ‹€μŒ λ°œμƒν•˜κ²Œ λ˜λŠ”Β componentDidUpdate Β ν•¨μˆ˜μ—μ„œ λ°›μ•„μ™€μ„œ μ‚¬μš©μ„ ν•  수 μžˆλ‹€.

ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈ + Hooksλ₯Ό μ‚¬μš©ν•  λ•Œ 이 λ©”μ„œλ“œλ₯Ό λŒ€μ²΄ν•  수 μžˆλŠ” κΈ°λŠ₯은 아직 μ—†λ‹€.

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

componentDidUpdate

componentDidUpdateΒ λŠ” λ¦¬λ Œλ”λ§μ΄ 마치고, 화면에 μš°λ¦¬κ°€ μ›ν•˜λŠ” λ³€ν™”κ°€ λͺ¨λ‘ 반영되고 λ‚œ λ’€ ν˜ΈμΆœλ˜λŠ” λ©”μ„œλ“œμ΄λ‹€. 3번째 νŒŒλΌλ―Έν„°λ‘œΒ getSnapshotBeforeUpdateΒ μ—μ„œ λ°˜ν™˜ν•œ 값을 쑰회 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

componentDidUpdate(prevProps, prevState, snapshot) {
  console.log("componentDidUpdate", prevProps, prevState);
  if (snapshot) {
    console.log("μ—…λ°μ΄νŠΈ 되기 직전 색상: ", snapshot);
  }
}

μ–Έλ§ˆμš΄νŠΈ

μ–Έλ§ˆμš΄νŠΈλΌλŠ”κ²ƒμ€, μ»΄ν¬λ„ŒνŠΈκ°€ ν™”λ©΄μ—μ„œ μ‚¬λΌμ§€λŠ”κ²ƒμ„ μ˜λ―Έν•œλ‹€. μ–Έλ§ˆμš΄νŠΈμ— κ΄€λ ¨λœ 생λͺ…μ£ΌκΈ° λ©”μ„œλ“œλŠ”Β componentWillUnmountΒ ν•˜λ‚˜μ΄λ‹€.

componentWillUnmount

componentWillUnmount Β λŠ” μ»΄ν¬λ„ŒνŠΈκ°€ ν™”λ©΄μ—μ„œ 사라지기 직전에 ν˜ΈμΆœλœλ‹€. 주둜 DOM에 직접 λ“±λ‘ν–ˆμ—ˆλ˜ 이벀트λ₯Ό μ œκ±°ν•˜κ³ , λ§Œμ•½μ—Β setTimeout 을 걸은것이 μžˆλ‹€λ©΄Β clearTimeout을 ν†΅ν•˜μ—¬ 제거λ₯Ό ν•œλ‹€.

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

였λ₯˜ 처리

μ•„λž˜ λ©”μ„œλ“œλ“€μ€ μžμ‹ μ»΄ν¬λ„ŒνŠΈλ₯Ό λ Œλ”λ§ν•˜κ±°λ‚˜, μžμ‹ μ»΄ν¬λ„ŒνŠΈκ°€ 생λͺ…μ£ΌκΈ° λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ±°λ‚˜, λ˜λŠ” μžμ‹ μ»΄ν¬λ„ŒνŠΈκ°€ μƒμ„±μž λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” κ³Όμ •μ—μ„œ 였λ₯˜κ°€ λ°œμƒν–ˆμ„ λ•Œμ— ν˜ΈμΆœλœλ‹€.

static getDerivedStateFromError()

이 생λͺ…μ£ΌκΈ° λ©”μ„œλ“œλŠ” ν•˜μœ„μ˜ μžμ† μ»΄ν¬λ„ŒνŠΈμ—μ„œ 였λ₯˜κ°€ λ°œμƒν–ˆμ„ λ•Œ ν˜ΈμΆœλœλ‹€. 단 render λ‹¨κ³„μ—μ„œ ν˜ΈμΆœλ˜λ―€λ‘œ, λΆ€μˆ˜ 효과λ₯Ό λ°œμƒμ‹œν‚€λ©΄ μ•ˆλœλ‹€. ν•΄λ‹Ή κ²½μš°μ—λŠ” componentDidCatchλ₯Ό λŒ€μ‹  μ‚¬μš©ν•˜μž.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // stateλ₯Ό κ°±μ‹ ν•˜μ—¬ λ‹€μŒ λ Œλ”λ§μ—μ„œ λŒ€μ²΄ UIλ₯Ό ν‘œμ‹œν•©λ‹ˆλ‹€.
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      // λ³„λ„λ‘œ μž‘μ„±ν•œ λŒ€μ²΄ UIλ₯Ό λ Œλ”λ§ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

componentDidCatch

이 생λͺ…μ£ΌκΈ° λ©”μ„œλ“œλŠ” μžμ† μ»΄ν¬λ„ŒνŠΈμ—μ„œ 였λ₯˜κ°€ λ°œμƒν–ˆμ„ λ•Œμ— 호좜되며, 2개의 λ§€κ°œλ³€μˆ˜λ₯Ό μ „λ‹¬λ°›λŠ”λ‹€. λ˜ν•œ 컀밋 λ‹¨κ³„μ—μ„œ ν˜ΈμΆœλœλ‹€.

componentDidCatch(error, info) {
  // error : λ°œμƒν•œ 였λ₯˜
  // info : μ–΄λ–€ μ»΄ν¬λ„ŒνŠΈκ°€ 였λ₯˜λ₯Ό λ°œμƒν–ˆλŠ”μ§€μ— λŒ€ν•œ 정보λ₯Ό ν¬ν•¨ν•œ componentStack ν‚€λ₯Ό κ°–κ³  μžˆλŠ” 객체
  logComponentStackToMyService(info.componentStack);
}

κ·Έ λ°–μ˜ 생λͺ…μ£ΌκΈ° λ©”μ„œλ“œ

μœ„μ—μ„œ μ„€λͺ…ν•œ 생λͺ…μ£ΌκΈ° λ©”μ„œλ“œλ“€κ³Ό 달리 μ•„λž˜μ˜ λ©”μ„œλ“œλ“€μ€Β μ‚¬μš©μžκ°€Β μ»΄ν¬λ„ŒνŠΈ λ‚΄μ—μ„œ 직접 ν˜ΈμΆœν•  수 μžˆλ‹€.

setState()

μ»΄ν¬λ„ŒνŠΈ state의 λ³€κ²½ 사항을 λŒ€κΈ°μ—΄μ— 집어넣고, Reactμ—κ²Œ ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈμ™€ κ·Έ μžμ‹λ“€μ΄ κ°±μ‹ λœ stateλ₯Ό μ‚¬μš©ν•˜μ—¬ λ‹€μ‹œ λ Œλ”λ§λ˜μ–΄μ•Ό ν•œλ‹€κ³  μ•Œλ¦°λ‹€. 인지 μ„±λŠ₯(Perceived Performance)의 ν–₯상을 μœ„ν•˜μ—¬ ReactλŠ” 이 λ©”μ„œλ“œμ˜ 싀행을 μ§€μ—°μ‹œν‚€κ³  μ—¬λŸ¬ μ»΄ν¬λ„ŒνŠΈλ₯Ό ν•œλ²ˆμ— κ°±μ‹ ν•  μˆ˜λ„ μžˆλ‹€.

λ‹€μŒ 챕터에 μžμ„Ένžˆ λ‹€λ€„λ³΄κ² μŠ΅λ‹ˆλ‹Ή~

forceUpdate()

component.forceUpdate(callback)

μ»΄ν¬λ„ŒνŠΈμ˜ state λ˜λŠ” propsκ°€ λ³€κ²½λ˜λ©΄, μ»΄ν¬λ„ŒνŠΈκ°€ λ‹€μ‹œ λ Œλ”λ§λ˜λŠ” 것이 κΈ°λ³Έ λ™μž‘μ΄λ‹€. μ–΄λ–€ μ»΄ν¬λ„ŒνŠΈμ˜Β render()Β λ©”μ„œλ“œκ°€ λ‹€λ₯Έ 데이터값에 μ˜μ‘΄ν•˜λŠ” 경우, React둜 ν•˜μ—¬κΈˆΒ forceUpdate()λ₯Ό ν˜ΈμΆœν•˜μ—¬ λ Œλ”λ§μ„ λ‹€μ‹œ μˆ˜ν–‰ν•˜λ„λ‘ λ§Œλ“€ 수 μžˆλ‹€.

πŸ”₯ λŠλ‚€μ 

계속 κ³΅μ‹λ¬Έμ„œλ₯Ό μ½μœΌλ©΄μ„œ 생λͺ…주기에 λŒ€ν•œ λ‚΄μš©μ΄ λ‚˜μ™€μ„œ κΌ­ μ‚΄νŽ΄λ³΄κ³  λ„˜μ–΄κ°€κ³  μ‹Άμ—ˆλ‹€. 비둝 μ§€κΈˆμ€ 자주 μ‚¬μš©ν•˜μ§€ μ•Šμ§€λ§Œ λ‚˜μ€‘μ— νšŒμ‚¬μ— λ“€μ–΄κ°€μ„œ λ ˆκ±°μ‹œ μ½”λ“œλ₯Ό λ§Œμ§€κ²Œ 될 μˆ˜λ„ μžˆμœΌλ‹ˆ μ•Œμ•„λ‘λŠ” 것이 쒋을 것 κ°™μ•˜λ‹€.
κ·Έλ™μ•ˆ ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚¬μš©ν•˜λ©΄μ„œ useEffect에 λŒ€ν•΄μ„œ μ•Œκ³ λ§Œ 있고 ν΄λž˜μŠ€ν˜• μ»΄ν¬λ„ŒνŠΈμ— λŒ€ν•΄μ„œλŠ” λͺ¨λ₯΄λŠ” μƒνƒœμ˜€λ‹€. 이번 기회둜 μ–΄λ–€ λ©”μ„œλ“œκ°€ 있고 μ–Έμ œ ν˜ΈμΆœλ˜λŠ”μ§€ μ•Œκ²Œ λ˜μ—ˆλ‹€.

Refer

profile
맀 μˆœκ°„ μ„±μž₯ν•˜λŠ” κ°œλ°œμžκ°€ 되렀고 λ…Έλ ₯ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

0개의 λŒ“κΈ€