Svelte Lifecycle에 대해서 알아보자! - OhMinsSup/tip-review GitHub Wiki

모든 컴포넌트에는 컴포넌트가 생성 될 때 시작되고 파괴 될 때 종료되는 수명주기가 있습니다. 해당 수명주기 동안 주요 순간에 코드를 실행할 수있는 몇 가지 기능이 있습니다.

1. onMount

가장 자주 사용하는되는 생명주기 함수는 컴포넌트가 DOM에 처음 렌더링 된 후 실행되는 onMount입니다.

<script>
  import { onMount } from "svelte";

  let photos = [];

  onMount(async () => {
    const res = await fetch(
      `https://jsonplaceholder.typicode.com/photos?_limit=20`
    );
    photos = await res.json();
  });
</script>

컴포넌트의 요소가 초기화되는 동안 생명주기 함수를 호출해야 콜백이 구성 요소 인스턴스에 바인딩 된다.

onMount 콜백 함수를 반환하면 컴포넌트 요소가 소멸 될 때 해당 함수가 호출됩니다. 즉, 삭제된다.

<script>
  import { onMount } from "svelte";

  let timeoutId = 0;

  onMount(async () => {
    timeoutId = setTimeout(() => {
      console.log("호출됨");
    }, 500);
    // destory
    return () => clearTimeout(timeoutId);
  });
</script>

한가지 추가적으로 설명을 하자면 서버 사이드 렌더링 (SSR)시 script 태그의 최상위 레벨이 아닌 onMount에 페치를 넣는 것이 좋습니다. (컴포넌트의 최상위 컴포넌트가 아닌 컴포넌트의 생명주기 함수) onDestroy를 제외하고 SSR 중에 생명주기 기능이 실행되지 않으므로 컴포넌트가 DOM에 마운트 된 후에 lazyload 되어야하는 데이터를 가져 오는 것을 피할 수 있습니다.

컴포넌트가 DOM에 마운트 된 후에 lazyload 되어야하는 데이터를 가져 오는 것을 피할 수 있습니다.

위에 적힌 내용이 처음에는 이해가 안됬는데 잘 생각을 해보면 답을 알 수 있다. 먼저 서버 사이드 렌더링이 아닌 상황에서 컴포넌트를 렌더링을 할 경우 먼저 컴포넌트가 그려지고 onMount 함수가 실행되고, 그 다음에 컴포넌트에서 해당 변화를 캐치해서 값을 바인딩을 합니다. 그러다보니 데이터가 지연로딩이 발생하는데, 서버 사이드 렌더링시에는 생명주기 함수가 onDestory 밖에 없기 때문에 위에서 설명한 절차대로 돔이 그려지지 않고 바로 그려지기 때문에 지연로딩을 피할 수 있다. 의미인것 같다.

2. onDestory

컴포넌트가 파괴될 때 생명주기 함수 onDestroy를 사용해야합니다. onDestory로 컴포넌트가 파괴될 때 더이상 관련없는 데이터들을 정리하면 메모리 누수가 방지될 수 있습니다.

<script>
  import { onDestory } from "svelte";

  let seconds = 0;
  const interval = setInterval(() => (seconds += 1), 1000);

  onDestroy(() => clearInterval(interval));
</script>

또한 onDestory 함수를 무조선 컴포넌트에서 호출 할 필요없이 모듈로써 관리하면서 호출해도 됩니다. 이건 정말 놀라운 기능인것 같습니다.

import { onDestroy } from "svelte";

export function onInterval(callback, milliseconds) {
  const interval = setInterval(callback, milliseconds);

  onDestroy(() => {
    clearInterval(interval);
  });
}
<script>
  import { onInterval } from "./utils.js";

  let seconds = 0;
  onInterval(() => (seconds += 1), 1000);
</script>

3. beforeUpdate & afterUpdate

beforeUpdate 함수는 DOM이 업데이트되기 직전에 발생하도록 작업을 예약합니다. afterUpdate는 대응되는 것으로 DOM이 데이터와 동기화되면 코드를 실행하는 데 사용됩니다.

컴포넌트가 마운트되기 전에 beforeUpdate가 먼저 실행되므로 속성을 읽기 전에 div가 있는지 확인해야합니다.

Svelte 예제

위 사이트가 정말 명확하게 이 함수들이 언제 사용해야하는지 알려줍니다.

4. tick

tick은 언제든지 호출할 수 있습니다. 컴포넌트(다른 컴포넌트를 포함)의 상태 변경이 DOM에 적용되면 바로 Promise(resolve) 객체를 반환합니다.

Promise로 랩핑된 nextTick?!

<script>
  import { tick } from 'svelte';

  let w = 100;
  let boxWidth = 100;

  function getRandomSize() {
    return parseInt(Math.random() * (500 - 100) + 100);
  }
  async function shuffleSize() {
    w = getRandomSize();
    await tick();
    boxWidth = document.querySelector('.box').getBoundingClientRect().width;
  }
</script>

<h2>Random W: {w}</h2>
<h2>Box Size: {boxWidth}</h2>
<div on:click={shuffleSize}
     style="width: {w}px;"
     class="box"></div>

<style>
  .box {
    height: 100px;
    background: tomato;
    border-radius: 10px;
    cursor: pointer;
  }
</style>
⚠️ **GitHub.com Fallback** ⚠️