Svelte

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

DevStory 2022. 8. 4.

쓰기 가능 스토어

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

 

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

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

developer-talk.tistory.com

이번 포스팅은 쓰기 가능 스토어의 값을 초기화하는 방법과 새로운 값을 할당하는 방법을 설명합니다.


초깃값 설정

초깃값을 설정하기 전에 쓰기 가능 스토어를 생성합니다. 스토어는 컴포넌트가 아니므로 .svelte 확장자가 아닌 .js 확장자로 스토어 파일을 생성합니다.

이번 포스팅은 WritableStore.js라는 파일에 쓰기 가능 스토어를 구현합니다. 스토어를 쓰기 가능 스토어로 설정하기 위해 svelte/store 패키지에 정의되어 있는 writable() 함수를 호출합니다.

 

[스토어 - WritableStore.js]

import {writable} from 'svelte/store';

export const writableData = writable([]);

스토어의 초깃값을 설정하기 위해서는 writable() 함수의 첫 번째 인자에 값을 할당합니다. WritableData 스토어의 초깃값은 빈 배열로 할당되었습니다.

 

그리고 스토어의 데이터가 다른 객체를 참조하지 못하도록 const 키워드로 선언합니다.


새로운 값을 할당

스토어의 데이터를 새로운 값으로 할당하고 싶다면, set() 함수를 사용합니다.

 

다음 예제는 App 컴포넌트가 WritableData를 구독하고 set() 함수를 사용하여 스토어의 데이터를 변경합니다.

 

[스토어 - WritableStore.js]

import {writable} from 'svelte/store';

export const writableData = writable(0);

WritableData 스토어의 초깃값은 0으로 설정됩니다.

 

[컴포넌트 - App.svelte]

<script>
  import { writableData } from './WritableStore.js';

  let value;
  
  // 스토어의 값이 변경되면 subscribe() 함수의 콜백 함수가 실행
  writableData.subscribe((data) => {
    value = data;
  });

  // 스토어의 값을 'Svelte'로 변경
  function setStoreValueSvelte() {
    writableData.set('Svelte');
  }

  // 스토어의 값을 0으로 변경
  function setStoreValueZero() {
    writableData.set(0);
  }
</script>

<div>
  <button on:click={setStoreValueSvelte}>
    스토어의 값을 "Svelte"로 할당
  </button>
  <button on:click={setStoreValueZero}>
    스토어의 값을 0으로 할당
  </button>
  <p>{value}</p>
</div>

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

[실행 결과]

App 컴포넌트는 subscribe() 함수를 호출하여 스토어의 데이터를 변수 value에 할당합니다. 스토어의 값이 변경될 때마다 subscribe() 함수에 전달된 콜백 함수가 실행되며 변수 value의 값이 재할당됩니다.

 

스토어의 값을 "Svelte"로 할당 버튼을 클릭하면 script 영역에 선언된 setStoreValueSvelte() 함수가 호출됩니다. setStoreValueSvelte() 함수는 스토어에서 제공하는 set() 함수를 호출하며, set() 함수의 인자로 문자열 "Svelte"를 전달합니다. 따라서 writableData 스토어의 값은 "Svelte"로 변경되고 HTML 영역에 변경된 값이 표기됩니다.

 

스토어의 값을 0으로 할당 버튼을 클릭하면 script 영역에 선언된 setStoreValueZero() 함수가 호출됩니다. setStoreValueZero() 함수는 스토어에서 제공하는 set() 함수를 호출하며, set() 함수의 인자로 숫자 0을 전달합니다. 따라서 writableData 스토어의 값은 0으로 변경되고 HTML 영역에 변경된 값이 표기됩니다.


writable 함수의 두 번째 인자

스토어의 writable() 함수는 두 번째 인자로 함수를 가질 수 있습니다. writable() 함수의 두 번째 인자로 전달된 함수는 set() 함수에 전달됩니다. 스토어를 처음으로 구독하는 컴포넌트가 존재하면 start 함수가 실행되고 구독이 취소되면 stop 함수가 실행됩니다.

 

다음 예제는 WritableData 스토어를 처음 구독하는 컴포넌트가 존재하면, 스토어의 값을 10으로 설정하며 구독이 취소되면 콘솔에 '구독 취소'를 출력합니다.

 

[스토어 - WritableStore.js]

import {writable} from 'svelte/store';

export const writableData = writable(0, set => {
  console.log('첫 구독');
  set(10);
  return () => {
    console.log('구독 취소');
  }
});

스토어를 처음 구독하는 컴포넌트가 존재하면 start 함수가 실행됩니다.

console.log('첫 구독');
set(10);

구독을 취소하면 return문에 작성된 stop 함수가 실행됩니다.

return () => {
  console.log('구독 취소');
}

 

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

App.svelte는 Child.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]

<script>
  import { onDestroy } from 'svelte';
  import {writableData} from './WritableStore.js';

  let value;
  
  const unsubscribe = writableData.subscribe((data) => {
    value = data;
  });

  onDestroy(unsubscribe);
</script>

<div>
    <span>{value}</span>
</div>

[실행 결과]

"Child 컴포넌트 활성화 버튼"을 클릭하면 Child 컴포넌트가 활성화되며, Child 컴포넌트가 WritableData 스토어의 최초 구독자이므로 writable() 함수의 두 번째 인자로 전달된 함수에서 start 함수가 실행됩니다.

 

"Child 컴포넌트 비활성화 버튼"을 클릭하면 Child 컴포넌트가 비활성화되면서 onDestory() 함수를 호출합니다. onDestory() 함수는 스벨트에서 제공하는 생명주기 함수입니다. DOM에서 컴포넌트가 제거될 때 호출하고 싶은 함수를 onDestory() 함수의 인자로 전달합니다.

 

onDestory() 함수에 unsubscribe() 함수를 전달하여 스토어의 구독을 취소합니다. 따라서 Child 컴포넌트가 비활성화되면 writable() 함수의 두 번째 인자로 전달된 함수에서 stop 함수가 실행됩니다.

반응형

댓글