Svelte

[Svelte]스토어 사용 방법 - 읽기 전용(readable)

DevStory 2022. 8. 3.

스토어(store)란?

지난 포스팅에서 스토어의 개념과 쓰기 가능 스토어를 생성는 방법을 알아보았습니다.

 

[Svelte]스토어 사용 방법 - 쓰기 가능(writable)

스토어(Store)란? 부모-자식 컴포넌트 간 데이터를 공유하는 방법으로 props를 사용할 수 있으며, 부모-자식 컴포넌트 구조가 아닌 컴포넌트 간에 데이터를 공유하는 방법으로 콘텍스트(Context)가 존

developer-talk.tistory.com

스토어는 컴포넌트 간 데이터를 공유하는 방법으로 컴포넌트 계층구조와 상관없이 데이터를 공유할 수 있습니다.

 

스토어는 컴포넌트가 아니므로 .svelte 확장자가 아닌 .js 확장자를 사용하여 스토어 파일을 생성할 수 있으며, 컴포넌트는 스토어에 값을 등록하거나 변경할 수 있습니다.

 

스벨트에서는 쓰기 가능 스토어, 읽기 전용 스토어, 상속 스토어와 같은 여러 유형의 스토어를 제공하며, 이번 포스팅은 읽기 전용 스토어에 대해 설명합니다.


읽기 전용 스토어

스토어에 등록된 값을 변경할 수 없는 스토어를 읽기 전용 스토어라고 말합니다. 읽기 전용 스토어는 svelte/store 패키지에 정의되어 있는 readable() 함수를 호출해서 만들 수 있습니다.

 

readable() 함수의 첫 번째 인자는 스토어 데이터의 초깃값이며, 두 번째 인자는 스토어에 새 값을 할당하는 set() 함수이며 생략 가능합니다.


스토어 만들기

읽기 전용 스토어를 만들기 위해 스토어 확장자가 .js인 파일을 생성합니다. ExampleReadableStore.js라는 스토어 파일을 생성했습니다.

그리고 readable() 함수를 사용하여 스토어의 데이터를 읽기 전용으로 만들고 초깃값을 20으로 설정합니다.

 

[스토어 - ExampleReadableStore.js]

import {readable} from 'svelte/store';

const numStore = readable(20);

export {numStore}

스토어 구독

스토어에 등록된 데이터를 가져오기 위해 컴포넌트에서 스토어를 구독합니다.

 

컴포넌트가 스토어를 구독하기 위해 subscribe() 함수에 콜백 함수를 전달하여 스토어에 등록된 데이터를 변수 num에 할당합니다.

 

[컴포넌트 - App.svelte]

<script>
  import {numStore} from './ExampleReadableStore.js';

  let num = 0;

  numStore.subscribe((data) => {
    num = data;
  });
</script>

<div>
  <span>{numStore}</span>
</div>

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

[실행 결과]


set() 함수를 사용하는 읽기 전용 스토어

이번에는 스토어에서 사용된 readable() 함수의 두 번째 인자로 set() 함수를 전달합니다.

 

다음 예제는 스토어의 데이터를 0으로 초기화하고 set() 함수를 통해 스토어의 데이터를 0.5초마다 1 증가시킵니다.

 

[스토어 - ExampleReadableStore.js]

import {readable} from 'svelte/store';

let initValue = 0;

const numStore = readable(initValue, set => {
  const token = setInterval(() => {
    initValue += 1;
    set(initValue);
  }, 500);
  return () => clearInterval(token);
});

export {numStore}

readable() 함수의 두 번째 인자로 전달된 set() 함수는 스토어를 구독하는 컴포넌트가 있으면 동작하고 구독하는 컴포넌트가 없는 경우 동작하지 않습니다.

 

즉, 컴포넌트가 스토어를 구독하면 setInterval() 함수가 호출되며 0.5초마다 스토어의 데이터를 1 증가시킵니다. 구독하는 컴포넌트가 없으면 clearInterval() 함수가 호출되며 setInterval() 함수를 중단시킵니다.

 

컴포넌트는 다음 사진처럼 App.svelte와 Child.svelte가 존재합니다.

App.svelte는 부모 컴포넌트이며, Child.svelte는 자식 컴포넌트입니다. App 컴포넌트에서 "Child 컴포넌트 활성화" 버튼을 클릭하면 Child 컴포넌트가 활성화되고 "Child 컴포넌트 비활성화" 버튼을 클릭하면 Child 컴포넌트가 비활성화됩니다.

 

[부모 컴포넌트 - 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.svelte는 ExampleReadableStore.js 파일의 numStore 스토어를 구독합니다. subscribe() 함수를 사용하지 않고 HTML 영역에 $ 기호를 사용하여 스토어의 데이터를 가져옵니다.

 

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

<script>
  import {numStore} from './ExampleReadableStore.js';
</script>

<div>
    <span>{$numStore}</span>
</div>

[실행 결과]

"Child 컴포넌트 활성화" 버튼을 클릭하면 Child 컴포넌트가 활성화되며, Child 컴포넌트가 numStore 스토어를 구독하므로 setInterval() 함수가 동작합니다.

 

"Child 컴포넌트 비활성화" 버튼을 클릭하면 Child 컴포넌트가 비활성화되며, Child 컴포넌트에서 numStore 스토어 구독이 해제됩니다. 따라서, clearInterval() 함수에 의해 setInterval() 함수가 중지됩니다.

 

다시 "Child 컴포넌트 활성화" 버튼을 클릭하면 Child 컴포넌트가 활성화되며 Child 컴포넌트가 numStore 스토어를 구독하며, 중지되었던 setInterval() 함수가 활성화됩니다.

반응형

댓글