Svelte

[Svelte]스벨트 생명주기 정리

DevStory 2022. 8. 9.

스벨트 생명주기

Svelte에 각 컴포넌트는 생명주기(LifeCycle)를 거칩니다. 사람이 태어나고 살다가 죽는 과정을 거치는 것처럼 컴포넌트는 DOM에 탑재되고 컴포넌트의 값이 변경되고 더 이상 필요하지 않을 때, DOM에서 제거되는 과정을 거칩니다.

 

Svelte는 다음과 같이 총 4개의 생명주기 함수를 제공합니다.

- 컴포넌트에서 변경된 값이 DOM에 반영되기 전에 실행되는 beforeUpdate() 함수

- 컴포넌트가 DOM에 추가될 때, 실행되는 onMount() 함수

- 컴포넌트에서 변경된 값이 DOM에 반영된 후 실행되는 afterUpdate() 함수

- 컴포넌트가 DOM에서 제거될 때, 실행되는 onDestroy() 함수

 

그리고 생명주기 함수는 아니지만, 특수한 목적으로 사용되는 함수도 존재합니다.

- props 또는 state가 DOM에 적용된 후 Promise 객체를 반환하는 tick() 함수


beforeUpdate 함수

beforeUpdate() 함수는 컴포넌트에서 변경된 값이 DOM에 반영되기 전에 호출되는 생명주기 함수입니다.

 

beforeUpdate() 함수는 다음 두 가지 상황에서 호출됩니다.

- 컴포넌트가 DOM에 추가되는 경우

- 컴포넌트에서 변경된 값이 DOM에 반영되기 전

 

다음 예제를 통해 beforeUpdate() 함수에 대해 알아봅시다.

 

App 컴포넌트에서 "Child 컴포넌트 활성화" 버튼을 클릭하면 Child 컴포넌트가 활성화되면서 Child 컴포넌트의 beforeUpdate() 함수가 호출됩니다.

 

그리고 Child 컴포넌트에서 "num++" 버튼을 클릭하면 Child 컴포넌트의 변수 numValue의 값이 변경되는데, 변경된 값이 DOM에 반영되기 전에 beforeUpdate() 함수가 호출됩니다.

 

[부모 컴포넌트 - App.svelte]

<script>
  import Child from './Child.svelte';

  let isInputElementView = false;

  const handleClick = (param) => {
    isInputElementView = param;
  }
</script>

<button on:click={() => handleClick(true)}>
  Child 컴포넌트 활성화
</button>

{#if isInputElementView}
  <Child />
{/if}

[자식 컴포넌트 - Child.svelte]

<script>
  import { beforeUpdate } from 'svelte';
  let numValue = 0;
  const handleClick = () => numValue++;

  beforeUpdate(() => console.log('Child Component beforeUpdate Call'));
</script>

<div>
  <button on:click={handleClick}>
    num++
  </button>
  <p>numValue: {numValue}</p>
</div>

beforeUpdate() 함수에 대한 추가적인 내용은 아래 포스팅에서 확인할 수 있습니다.

 

[Svelte]생명주기(Lifecycle) - beforeUpdate 함수

beforeUpdate 함수 Svelte의 생명주기 함수인 beforeUpdate() 함수는 컴포넌트의 변경된 값이 DOM에 적용되기 전에 호출됩니다. 즉, 변경된 값이 DOM에 영향이 있으면 호출되고 영향이 없으면 호출되지 않습

developer-talk.tistory.com


onMount 함수

onMount() 함수는 컴포넌트가 DOM에 추가될 때 호출됩니다. 컴포넌트가 DOM에 추가될 때, 최초 한 번만 실행해야 하는 작업을 onMount() 함수에 작성합니다.

 

주로 아래 작업을 처리해야 하는 경우 onMount() 함수를 사용합니다.

- 컴포넌트에 필요한 데이터 가져오기

- 컴포넌트에 필요한 데이터 변환하기

- DOM 요소 접근하기(포커싱 처리 등...)

 

다음 예제를 통해 onMount() 함수에 대해 알아봅시다.

 

App 컴포넌트에서 "Child 컴포넌트 활성화" 버튼을 클릭하면 Child 컴포넌트가 활성화되면서 Child 컴포넌트의 onMount() 함수가 호출됩니다.

 

App 컴포넌트에서 "Child 컴포넌트 비활성화" 버튼을 클릭하면 Child 컴포넌트가 제거되며, "Child 컴포넌트 활성화" 버튼을 클릭하면 Child 컴포넌트가 다시 활성화되면서 Child 컴포넌트의 onMount() 함수가 호출됩니다.

 

[부모 컴포넌트 - App.svelte]

<script>
  import Child from './Child.svelte';

  let isInputElementView = false;

  const handleClick = (param) => {
    isInputElementView = param;
  }
</script>

<button on:click={() => handleClick(true)}>
  Child 컴포넌트 활성화
</button>

<button on:click={() => handleClick(false)}>
  Child 컴포넌트 비활성화
</button>

{#if isInputElementView}
  <Child />
{/if}

[자식 컴포넌트 - Child.svelte]

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

  onMount(() => console.log('Child Component onMount Call'));
</script>

<h1>Child Component</h1>

onMount() 함수에 대한 추가적인 내용은 아래 포스팅에서 확인할 수 있습니다.

 

[Svelte]생명주기(Lifecycle) - onMount 함수

onMount 함수 Svelte의 생명주기 함수인 onMount()는 컴포넌트가 DOM에 추가될 때 호출됩니다. 컴포넌트가 DOM에 추가될 때, 최초 한 번만 실행해야 하는 작업을 작성할 수 있습니다. onMount() 함수는 주로

developer-talk.tistory.com


afterUpdate 함수

afterUpdate() 함수는 컴포넌트에서 변경된 값이 DOM에 반영된 후 호출되는 생명주기 함수입니다. 변경된 값이 DOM에 표시하지 않으면, 호출되지 않습니다.

 

다음 예제를 통해 afterUpdate() 함수에 대해 알아봅시다.

 

App 컴포넌트에서 "Child 컴포넌트 활성화" 버튼을 클릭하면 Child 컴포넌트가 활성화되면서 Child 컴포넌트의 afterUpdate() 함수가 호출됩니다.

 

그리고 Child 컴포넌트에서 "num++" 버튼을 클릭하면 Child 컴포넌트의 변수 numValue의 값이 변경되는데, 변경된 값이 DOM에 반영 후 afterUpdate() 함수가 호출됩니다.

 

[부모 컴포넌트 - App.svelte]

<script>
  import Child from './Child.svelte';

  let isInputElementView = false;

  const handleClick = (param) => {
    isInputElementView = param;
  }
</script>

<button on:click={() => handleClick(true)}>
  Child 컴포넌트 활성화
</button>

{#if isInputElementView}
  <Child />
{/if}

[자식 컴포넌트 - Child.svelte]

<script>
  import { afterUpdate } from 'svelte';
  let numValue = 0;
  const handleClick = () => numValue++;

  afterUpdate(() => console.log('Child Component afterUpdate Call'));
</script>

<h1>Child Component</h1>
<div>
  <button on:click={handleClick}>
    num++
  </button>
  <p>numValue: {numValue}</p>
</div>

afterUpdate() 함수에 대한 추가적인 내용은 아래 포스팅에서 확인할 수 있습니다.

 

[Svelte]생명주기(Lifecycle) - afterUpdate 함수

afterUpdate 함수 Svelte의 생명주기 함수인 afterUpdate() 함수는 컴포넌트의 변경된 값이 DOM에 적용 후 호출됩니다. 즉, 변경된 값이 DOM에 영향이 있으면 호출되고 영향이 없으면 호출되지 않습니다. 다

developer-talk.tistory.com

반응형

onDestroy 함수

onDestroy() 함수는 컴포넌트가 DOM에서 제거될 때 호출됩니다.

 

주로 아래 작업을 처리해야 하는 경우 onDestroy() 함수를 사용합니다.

- 컴포넌트가 다이어로그인 경우 다이어로그가 닫힌 후 메인 컴포넌트에 포커스 처리

- 사용자 활동 기록을 로그로 남기는 경우

- subscribe() 함수로 스토어를 구독했을 때, 스토어 구독을 취소하기 위해 사용

 

다음 예제를 통해 onDestroy() 함수에 대해 알아봅시다.

 

App 컴포넌트에서 "Child 컴포넌트 활성화" 버튼을 클릭하면 Child 컴포넌트가 활성화됩니다.

 

Child 컴포넌트가 활성화된 상태에서 "Child 컴포넌트 비활성화" 버튼을 클릭하면 Child 컴포넌트가 DOM에서 제거되므로 Child 컴포넌트의 onDestroy() 함수가 호출됩니다.

 

[부모 컴포넌트 - App.svelte]

<script>
  import Child from './Child.svelte';

  let isInputElementView = false;

  const handleClick = (param) => {
    isInputElementView = param;
  }
</script>

<button on:click={() => handleClick(true)}>
  Child 컴포넌트 활성화
</button>

<button on:click={() => handleClick(false)}>
  Child 컴포넌트 비활성화
</button>

{#if isInputElementView}
  <Child />
{/if}

[자식 컴포넌트 - Child.svelte]

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

  onDestroy(() => console.log('Child Component onDestroy Call'));
</script>

<h1>Child Component</h1>

onDestroy() 함수에 대한 추가적인 내용은 아래 포스팅에서 확인할 수 있습니다.

 

[Svelte]생명주기(Lifecycle) - onDestroy 함수

onDestroy 함수 Svelte의 생명주기 함수인 onDestroy() 함수는 컴포넌트가 DOM에서 제거될 때 호출됩니다. 컴포넌트가 DOM에서 제거될 때 실행되어야 하는 소스 코드 또는 함수를 인자로 전달합니다. 다음

developer-talk.tistory.com


생명주기 함수 실행 순서

컴포넌트가 DOM에 추가되는 경우 생명주기 함수는 다음 순서대로 실행됩니다.

beforeUpdate() → onMount() → afterUpdate()

 

컴포넌트가 DOM에 추가된 상태에서 제거되는 경우 onDestroy() 함수가 호출됩니다.

onDestroy()

 

컴포넌트가 DOM에 추가된 상태에서 값이 변경되는 경우 beforeUpdate() 함수와 afterUpdate() 함수가 호출됩니다.

값 변경 → beforeUpdate() → 변경된 값 DOM에 적용 → afterUpdate()

 

컴포넌트가 DOM에 추가된 상태에서 값을 변경했지만, DOM에 영향이 없는 경우 beforeUpdate() 함수와 afterUpdate() 함수는 호출되지 않습니다.

 

즉, 다음 소스 코드는 버튼을 클릭하면 변수 numValue의 값을 1씩 증가시키지만 DOM에 영향이 없으므로 beforeUpdate() 함수와 afterUpdate() 함수가 호출되지 않습니다.

<script>
  import { beforeUpdate, onMount, afterUpdate, onDestroy } from 'svelte';
  let numValue = 0;
  const handleClick = () => numValue++;

  beforeUpdate(() => console.log('Child Component beforeUpdate Call'));
  onMount(() => console.log('Child Component onMount Call'));
  afterUpdate(() => console.log('Child Component afterUpdate Call'));
  onDestroy(() => console.log('Child Component onDestroy Call'));
</script>

<h1>Child Component</h1>
<div>
  <button on:click={handleClick}>
    num++
  </button>
</div>

[실행 결과]


특수 함수 - tick

컴포넌트에서 값이 변경되면 변경된 값이 DOM에 바로 반영되지 않습니다. 따라서, 변경된 값이 DOM에 반영되기 전에 DOM 요소를 접근하는 경우 TypeError가 발생합니다.

 

다음 예제는 컴포넌트에서 변수 isInputElementView의 값을 변경하고 DOM 요소를 접근하면 TypeError가 발생합니다.

<script>
  let strValue = '';    
  let isInputElementView = false;
  let inputBind;

  const handleClick = (param) => {
    isInputElementView = param;
    if(isInputElementView === true) {
      inputBind.focus();
    }
  }
</script>

<button on:click={() => handleClick(true)}>
  input 태그 활성화
</button>

<button on:click={() => handleClick(false)}>
  input 태그 비활성화
</button>

{#if isInputElementView}
<div>
  <input type="text" bind:value={strValue} bind:this={inputBind} />
</div>
{/if}

[실행 결과]

컴포넌트의 변경된 값이 DOM에 반영 후 특정 로직이 실행되어야 하는 경우 tick() 함수를 사용합니다. tick() 함수는 Promise 객체를 반환하며, 다음 소스 코드처럼 async와 await 키워드를 사용할 수 있습니다.

const handleClick = async (param) => {
  isInputElementView = param;
  await tick(); // DOM 적용될 때까지 기다립니다.
  if(param === true) {
    inputBind.focus(); 
  }
}

참고로 tick() 함수는 생명주기 함수가 아닙니다. Svelte의 생명주기 함수의 타입이 정의된 lifecycle.d.ts 파일에 tick() 함수가 없는 것을 확인할 수 있습니다.

tick() 함수에 대한 추가적인 내용은 아래 포스팅에서 확인할 수 있습니다.

 

[Svelte]DOM 적용 후 실행되는 tick 함수

tick 함수 svelte에서 제공하는 tick() 함수는 props 또는 state가 DOM에 적용되자마자 Promise 객체를 반환합니다. 쉽게 설명하자면, script 영역에 선언된 변수의 값이 변경된 후 컴포넌트 또는 DOM 요소가 DO

developer-talk.tistory.com

반응형

댓글