Svelte

[Svelte]스토어 구독 방법

DevStory 2022. 8. 4.

스토어 구독 방법

Svelte에는 구독이란 개념이 존재하며, Youtube의 구독과 동일합니다. Youtube에서 특정 채널을 구독하고 해당 채널에 동영상이 업로드되면 알림을 받습니다.

 

Svelte에서 컴포넌트는 사용자이며, 채널은 스토어입니다. 컴포넌트가 스토어를 구독하고 스토어의 값이 변경되면 스토어를 구독하는 컴포넌트에게 변경된 값이 전달됩니다.

 

컴포넌트에서 스토어를 구독하는 방법은 두 가지입니다. 첫 번째 방법은 subscribe() 함수를 사용하는 방법이고 두 번째 방법은 자동 구독 표기법인 달러 $ 기호를 사용합니다.


예제 코드

다음 사진은 이번 포스팅에서 사용되는 컴포넌트와 스토어입니다.

App.svelte 컴포넌트는 Child.svelte의 부모 컴포넌트이며, Child.svelte는 자식 컴포넌트입니다.

 

[스토어 - ExampleStore1.js]

import {writable} from 'svelte/store';

export const ExampleStore1 = writable(0, set => {
  console.log('ExampleStore1 스토어 첫 구독');
  return () => {
    console.log('ExampleStore1 스토어 구독 취소');
  }
});

ExampleStore1 스토어는 초깃값을 0으로 설정합니다. 첫 구독이 발생하면 콘솔에 "ExampleStore1 스토어 첫 구독"을 출력하며, 구독이 취소되면 콘솔에 "ExampleStore1 스토어 구독 취소"를 출력합니다.

 

[스토어 - ExampleStore2.js]

import {writable} from 'svelte/store';

export const ExampleStore2 = writable(100, set => {
  console.log('ExampleStore2 스토어 첫 구독');
  return () => {
    console.log('ExampleStore2 스토어 구독 취소');
  }
});

ExampleStore2 스토어는 초깃값을 100으로 설정합니다. 첫 구독이 발생하면 콘솔에 "ExampleStore2 스토어 첫 구독"을 출력하며, 구독이 취소되면 콘솔에 "ExampleStore2 스토어 구독 취소"를 출력합니다.

 

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

 

[Svelte]쓰기 가능 스토어 초기화 및 새로운 값 할당

쓰기 가능 스토어 Svelte의 컴포넌트가 스토어의 값을 변경할 수 있으면, 해당 스토어는 쓰기 가능 스토어라고 말합니다. 아래 포스팅에서 스토어의 개념과 쓰기 가능 스토어를 구현하는 방법을

developer-talk.tistory.com

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

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

  let isChild = false;
</script>

<div>
  <button on:click={() => isChild = true}>Child 컴포넌트 활성화</button>
  <button on:click={() => isChild = false}>Child 컴포넌트 비활성화</button>
  {#if isChild === true}
    <div>Child 컴포넌트 활성화 상태</div>
    <Child />
  {:else}
    <div>Child 컴포넌트 비활성화 상태</div>
  {/if}
</div>

<style>
div {
  text-align: center;
}
</style>

[실행 결과]

"Child 컴포넌트 활성화" 버튼을 클릭하면 Child 컴포넌트가 활성화되면서 첫 구독이 발생하고 "Child 컴포넌트 비활성화" 버튼을 클릭하면 Child 컴포넌트가 비활성화되면서 구독 취소됩니다.

 

이번 포스팅은 스토어를 구독하는 Child 컴포넌트 위주로 설명합니다.


방법 1. subscribe 함수

스토어를 구독하는 컴포넌트에서 subscribe() 함수를 사용합니다. subscribe() 함수는 스토어에서 제공됩니다.

 

다음 예제는 subscribe() 함수에 스토어의 값을 변수 value1, value2에 할당하는 콜백 함수를 전달합니다.

 

[Child.svelte]

<script>
  import { ExampleStore1 } from './ExampleStore1.js';
  import { ExampleStore2 } from './ExampleStore2.js';

  let value1, value2;

  ExampleStore1.subscribe((data) => {
    value1 = data;
  });
  
  ExampleStore2.subscribe((data) => {
    value2 = data;
  });
</script>

<div>
    <p>ExampleStore1 스토어의 데이터: {value1}</p>
    <p>ExampleStore2 스토어의 데이터: {value2}</p>
</div>

[실행 결과]

위 소스 코드의 문제점은 "Child 컴포넌트 비활성화" 버튼을 클릭했을 때 Child 컴포넌트가 비활성화되지만 스토어 구독은 취소되지 않습니다.

 

따라서, Child.svelte에 스토어 구독을 취소하는 코드를 작성합니다.

 

[Child.svelte]

<script>
  import { onDestroy } from 'svelte';
  import { ExampleStore1 } from './ExampleStore1.js';
  import { ExampleStore2 } from './ExampleStore2.js';

  let value1, value2;

  const unsubscribe1 = ExampleStore1.subscribe((data) => {
    value1 = data;
  });

  const unsubscribe2 = ExampleStore2.subscribe((data) => {
    value2 = data;
  });

  onDestroy(unsubscribe1);
  onDestroy(unsubscribe2);
</script>

<div>
    <p>ExampleStore1 스토어의 데이터: {value1}</p>
    <p>ExampleStore2 스토어의 데이터: {value2}</p>
</div>

스벨트에서 제공하는 onDestry() 함수는 생명주기 함수입니다. DOM에서 컴포넌트가 제거될 때 호출하고 싶은 함수를 onDestory() 함수의 인자로 전달합니다.

 

즉, Child 컴포넌트가 DOM에서 제거될 때, 스토어를 구독하는 함수를 onDestory() 함수에 전달하여 스토어의 구독을 취소합니다.


방법 2. 자동 구독

스토어에서 제공하는 subscribe() 함수의 단점은 처리해야 하는 로직이 많다는 것입니다. $ 기호를 사용하면 스토어를 자동으로 구독할 수 있으며, 컴포넌트가 DOM에서 제거될 때 자동으로 구독 취소합니다.

 

자동 구독 표기법인 $ 기호는 컴포넌트의 HMTL 영역에서만 사용할 수 있습니다.

 

[Child.svelte]

<script>
  import { onDestroy } from 'svelte';
  import { ExampleStore1 } from './ExampleStore1.js';
  import { ExampleStore2 } from './ExampleStore2.js';
</script>

<div>
    <p>ExampleStore1 스토어의 데이터: {$ex1}</p>
    <p>ExampleStore2 스토어의 데이터: {$ex2}</p>
</div>
반응형

댓글