1. Svelte stores를 생성하고 타입을 정의
// store.ts
import { writable } from 'svelte/store';
interface CounterStore {
count: number;
increment: () => void;
decrement: () => void;
}
function createCounterStore() {
const { subscribe, update } = writable<CounterStore>({
count: 0,
increment: () => {},
decrement: () => {},
});
return {
subscribe,
increment: () => {
update((state) => {
state.count += 1;
return state;
});
},
decrement: () => {
update((state) => {
state.count -= 1;
return state;
});
},
};
}
export const counterStore = createCounterStore();
/**
(newVal, oldVal) => {
// 처리
}
*/
2.Svelte 컴포넌트에서 Store 사용하기
Store를 정의한 후에는 Svelte 컴포넌트에서 해당 Store를 사용할 수 있다.
// Counter.svelte
<script lang="ts">
import { counterStore } from './store';
</script>
<h1>Counter: {$counterStore.count}</h1>
<button on:click={$counterStore.increment}>Increment</button>
<button on:click={$counterStore.decrement}>Decrement</button>
subscribe : Svelte에서 상태 변화를 감지하고 컴포넌트가 해당 상태에 반응할 수 있도록 해주는 중요한 메서드. Store 객체가 가지고 있는 메서드 중 하나로, 컴포넌트가 Store의 상태를 구독할 때 사용.
Svelte의 상태 관리 시스템은 리액티브 방식으로 동작합니다. subscribe를 사용하면 Store의 상태가 변경될 때마다 해당 상태를 구독 중인 컴포넌트들에게 알려주고, 컴포넌트는 변경된 상태를 반영하여 UI를 업데이트할 수 있습니다.
간단한 예시로 설명하면, Store의 subscribe 메서드는 함수를 인자로 받고 이 함수는 Store의 상태가 변경될 때마다 호출된다. 그리고 이 함수 내부에서 컴포넌트가 변경된 상태를 처리하고 UI를 업데이트할 수 있다.
<script>
import { counterStore } from './store';
let count = 0;
counterStore.subscribe((store) => {
count = store.count;
});
</script>
<h1>Counter: {count}</h1>
<button on:click={$counterStore.increment}>Increment</button>
<button on:click={$counterStore.decrement}>Decrement</button>
위의 예시에서 counterStore.subscribe를 사용하여 count 상태를 구독하고 있다.
Store의 count가 변경될 때마다 subscribe에 전달한 함수가 호출되며, count 값을 업데이트하여 UI가 반응한다.
즉, subscribe를 사용하여 Store의 상태를 감지하고, 그에 따라 컴포넌트의 상태와 UI를 업데이트하는 것이 Svelte의 리액티브한 동작 원리 라고 할 수 있다.
update : Svelte Store의 메서드 중 하나로, 상태 값을 업데이트할 때 사용되는 메서드. update를 사용하면 기존 상태 값을 수정하거나 변경할 수 있고, update 메서드는 리액티브한 방식으로 상태가 변경되도록 도와주며, 상태의 변경을 안전하게 처리할 수 있도록 한다.
update 메서드는 함수를 인자로 받는데 이 함수는 현재 Store의 상태를 인자로 받아서 변경된 상태를 반환해야 한다. update 메서드는 변경된 상태를 적용하고 컴포넌트를 다시 렌더링합니다. 이를 통해 상태 변경에 따른 UI 업데이트를 자연스럽게 처리할 수 있다.
간단한 예시
<script>
import { counterStore } from './store';
function increase() {
$counterStore.update(store => {
return { count: store.count + 1 };
});
}
</script>
<h1>Counter: {$counterStore.count}</h1>
<button on:click={increase}>Increase</button>
increase 함수 내부에서 update 메서드를 사용하여 count 상태를 변경.
update는 현재 상태를 인자로 받은 뒤, 변경된 상태를 반환해야 하는데 이렇게 함으로써 상태의 변경을 안전하게 처리하면서 컴포넌트가 적절하게 리렌더링 된다.
즉, update를 사용하면 상태 값을 업데이트하고, 그에 따른 UI 변경을 리액티브하게 처리.
Svelte에서 Store 값을 받아올 때, $ 기호 없이도 Store를 import하고 사용할 수 있는 방법.
기본적으로는 $를 붙여서 Store를 참조하는 것이 Svelte의 관습이지만, 필요에 따라 아래와 같은 방법으로도 사용
subscribe 사용: $를 사용하지 않고도 Store의 값을 받아오기.
subscribe 메서드를 사용하여 Store를 구독한 후, 해당 값을 사용할 수 있다.
<script>
import { counterStore } from './store';
let count = 0;
counterStore.subscribe(store => {
count = store.count;
});
</script>
!!
그러나 Store의 리액티브한 동작을 활용하기 위해서는
$를 사용하여 Store를 참조하는 것이 일반적이고 추천되는 방법
!!
get 메서드는 Store의 현재 상태 값을 반환하며, 리액티브한 업데이트는 일어나지 않는다. 따라서 컴포넌트의 상태가 변경되어도 리렌더링되지 않음.
// get 메서드를 사용하여 Store 값을 받아오는 예시
<script>
import { counterStore } from './store';
let count = counterStore.get().count;
</script>
<h1>Counter: {count}</h1>
counterStore.get().count를 사용하여 count 값을 받아오고 있는데, 이 방식은 Store의 리액티브한 동작을 활용하지 않으며, 상태가 변경되어도 컴포넌트의 리렌더링은 일어나지 않는다.
subscribe와 get의 선택은 사용하려는 상황에 따라 다를 수 있기때문에 리액티브한 동작이 필요한 경우에는 subscribe를 사용하여 Store를 구독하는 것이 좋다.