Svelte의 store는 마치 react의 redux와 같습니다.
전역으로 상태관리가 필요할 때 사용하는 것으로
부모의 속성을 자식의 자식의 자식의 ... 자식까지 전달하려면
상위 자식에게 props를 주고, 그 자식은 또 하위 자식에게 props를 주고... 이렇게 최하위까지 전달이 되어야 하는 구조입니다.
이런 번거로운 과정을 없애기 위해 부모-자식 트리 외에 store라는 별도의 공간을 두고
이 공간에서 전역으로 관리할 상태를 생성하여 적재적소에 맞게 가져다 사용하면 됩니다.
글로만 이해하면 어려우니 한 번 예시를 통해 알아보겠습니다.
App.svelte
<script>
import Parent from './Parent.svelte'
let temp = '123';
</script>
<div>
App!!
</div>
<Parent temp={temp}/>
Parent.svelte
<script>
import Child1 from "./ChildOne.svelte"
export let temp;
</script>
<div>
Parents!
</div>
<Child1 temp={temp}/>
ChildOne.svelte
<script>
import ChildTwo from './ChildTwo.svelte'
export let temp;
</script>
<div>
child1
</div>
<ChildTwo temp={temp}/>
ChildTwo.svelte
<script>
export let temp;
</script>
<div>
Child2 {temp}
</div>
결과
자, 위의 예시는 최상단 App 컴포넌트에서 선언된 temp 변수의 값이
하위의 Parent 하위의 ChildOne 하위의 ChildTwo까지 전달되어 출력하는 로직입니다.
temp의 값은 ChildTwo까지 내려가면서 그 상위 부모 요소를 한 번씩 전부 거쳤습니다.
어떤가요?? 너무 귀찮고 불필요하지 않나요??
이제 Store에 대해서 한 번 알아보겠습니다.
먼저 store.js를 생성합니다.
store.js
import {writable} from 'svelte/store'
//temp는 writable로 선언된 변수이기 때문에 스토어 객체가 된다.
export let temp = writable('123');
store.js에서는 writable이라는 녀석을 통해 temp에 '123'이라는 초기값을 설정해주었습니다.
그리고 App부터 ChildTwo를 다시 작성해줍니다.
App.svelte
<script>
import Parent from './Parent.svelte'
</script>
<div>
App!!
</div>
<Parent/>
Parent.svelte
<script>
import Child1 from "./ChildOne.svelte"
</script>
<div>
Parents!
</div>
<Child1/>
ChildOne.svelte
<script>
import ChildTwo from './ChildTwo.svelte'
</script>
<div>
child1
</div>
<ChildTwo/>
ChildTwo.svelte
<script>
import {temp} from './store.js';
export let temp;
</script>
<div>
Child2 {$temp}
</div>
먼저 결과를 보고 코드를 다시 분석해봅시다!
결과는 첫 번째 예시와 동일합니다.
그런데 App 컴포넌트부터 Parent, ChildOne을 거쳐 ChildTwo에 도달하던 temp 속성이 사라졌습니다.
대신 ChildTwo 컴포넌트에서 store에 있는 temp를 가져와 사용하도록 변경되었네요.
그런데 이처럼 컴포넌트에서 store 객체를 import해서 사용할 때 주의할점이 있습니다.
바로 '$' 기호인데요,
store.js에서 writable로 선언된 변수를 그대로 사용하면, 최초 선언한 '123'의 값이 아닌 svelt/store 객체 그대로를 사용하겠다는 의미입니다.
즉, '123'의 값을 가진 temp를 사용하려면 앞에 $ 기호를 붙여줘야 합니다.
추가로 update와 set에 대해 알아봅시다.
먼저 childTwo 컴포넌트를 아래와 같이 변경해줍니다.
childTwo.svelte
<script>
import {temp} from './store.js';
const updateTemp = () => {
temp.update(n => n + '1');
}
const setTemp = () => {
temp.set('123');
}
</script>
<div>
child2 {$temp}
</div>
<button on:click={updateTemp}>Update!</button>
<button on:click={setTemp}>set!</button>
update와 set을 통해 store에 선언된 temp 변수의 값을 바꿔줄 수 있습니다.
temp는 스토어 객체이기 때문에
temp = '234';
이런식으로 변경할 수는 없으며, 따라서 update 혹은 set을 통해 변경해주어야합니다.
결과
둘 다 temp의 값을 변경시키는 기능을 담당하는데
update는 지속적으로 수정사항이 발생하거나, 갱신될 때
set은 초기 값으로 되돌아가야 할 때
등으로 나누어 사용하면 될 것 같습니다.
그럼 이만 포스팅을 마무리하겠습니다.