์ด๋ฒ์ฃผ์๋ ์คํ์ผ ์ ์ด(CSS, ์ ๋๋ฉ์ด์
, ๋ชจ์
, ํธ๋์ง์
)์ DOM ์ ์ด(์ก์
, ํน๋ณ์์)๋ฅผ ๊ณต๋ถํ๊ณ 2๊ฐ์ ํ๋ก์ ํธ๋ฅผ ์ค์ตํด๋ณด์๋ค. ์ด๋ฒ ๊ธ์ ์ค์ต์์ ๋๋ ๊ฒ ์์ฃผ๋ก ์์ฑํด๋ด!
Luvit ํ๋ฌ ์คํฐ๋
๐ชฃํ๋ก์ ํธ: My Bucket List
๊ฐ๋จํ ํฌ๋ ํ๋ก์ ํธ๋ฅผ ํด๋ณด์๋ค. UI ๊ตฌํ, props ํ์ฉ๊ณผ props->store๋ก ๋ฆฌํฉํ ๋ง ๊น์ง ์ ์ง์ ์ผ๋ก ๊ธฐ๋ฅ์ ํ์ฅํ๋ฉฐ Svelte์ ํต์ฌ ๊ฐ๋
์ ์ฒดํํ ์ ์๋ ํ๋ก์ ํธ์๋ค. ์๋๋ ์ฃผ์ ํ์ต ๋ด์ฉ๊ณผ ๋๋์ ๋ค
์ปดํฌ๋ํธ
UI๋ฅผ ๊ธฐ๋ฅ ๋จ์๋ก ๋ถ๋ฆฌํด์ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑํ๋ค. ํค๋(BucketHeader), ๋ฆฌ์คํธ(BucketList), ์์ดํ
(BucketItem), ์
๋ ฅ ํผ(BucketCreate) ๋ฑ์ผ๋ก ์ปดํฌ๋ํธ๋ฅผ ๋๋์ด ๊ฐ๋ฐํจ์ผ๋ก์จ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ผ ์ ์๋ค.
App.svelte์์๋ ๊ฐ ์ปดํฌ๋ํธ๋ฅผ ์กฐํฉํ์ฌ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์
๊ตฌ์กฐ๋ฅผ ์์ฑํ๋ค.
<script>
import BucketHeader from "./components/BucketHeader.svelte";
import BucketList from "./components/BucketList.svelte";
import BucketCreate from "./components/BucketCreate.svelte";
</script>
<svelte:head>
<title>My Bucket List</title>
</svelte:head>
<div class="bucketbox">
<BucketHeader />
<BucketList />
<BucketCreate />
</div>
๋ฐ์ดํฐ ๊ด๋ฆฌ(Props, Store)
1. Props๋ฅผ ์ด์ฉํ ๋ฐ์ดํฐ ์ ๋ฌ
ํ๋ก์ ํธ ์ฒ์์๋ ์์ ์ปดํฌ๋ํธ์ธ App.svelte๊ฐ ๋ชจ๋ ์ํ๋ฅผ ์์ ํ๊ณ , ์์ ์ปดํฌ๋ํธ์๊ฒ Props๋ฅผ ํตํด ๋ฐ์ดํฐ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ์์ ์ฌ์ฉํ๋ค. ๋ฐ์ดํฐ ํ๋ฆ์ด ๋ช
ํํ๋ค๋ ์ฅ์ ์ด ์์ง๋ง, ์ปดํฌ๋ํธ ๊ตฌ์กฐ๊ฐ ๊น์ด์ง์๋ก ์ค๊ฐ ์ปดํฌ๋ํธ๋ค์ด ์ฌ์ฉํ์ง ์๋ props๋ฅผ ์ ๋ฌํด์ผ ํ๋ props drilling์ด ๋ฐ์ํ ์ ์๋ ๊ตฌ์กฐ์๋ค.
2. ์คํ ์ด๋ฅผ ํตํ ์ ์ญ ์ํ ๊ด๋ฆฌ
props drilling ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ , ์ํ ๊ด๋ฆฌ๋ฅผ ๋์ฑ ํจ์จ์ ์ผ๋ก ํ๊ธฐ ์ํด ์คํ ์ด๋ฅผ ํ์ฉํ๋๋ก ๋ฆฌํฉํ ๋ง์ ์งํํ๋ค. store.js ํ์ผ์ ์ปค์คํ
์คํ ์ด๋ฅผ ์์ฑํ์ฌ ๋ฐ์ดํฐ์ ๊ด๋ จ๋ ๋ก์ง์ ํ ๊ณณ์์ ๊ด๋ฆฌํ๋ค.
์คํ ์ด๋ writable, derived ์คํ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์
์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ์ธ ๊ฐ์ ์ปค์คํ
์คํ ์ด๋ฅผ ๋ง๋ค์๋ฐ.
setBucketData
์ฃผ์ ๋ฐ์ดํฐ ๋ฐ ์ก์ ๊ด๋ฆฌ
writable ์คํ ์ด๋ฅผ ๊ฐ์ธ ๋ฒํท ๋ฆฌ์คํธ์ ๋ฐ์ดํฐ(buckets)์ ์์ ๋ชจ๋ ์ํ(editMode)๋ฟ๋ง ์๋๋ผ, ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ๋ ๋ชจ๋ ํจ์(onToggle, onRemove, onSubmin ๋ฑ)๋ฅผ ํ๋์ ๊ฐ์ฒด๋ก ๋ฌถ์ด ๋ฐํํ๋ ์ปค์คํ ์คํ ์ด์ด๋ค. ๋ฐ์ดํฐ์ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๋ก์ง์ ํจ๊ป ์บก์ํํ์ฌ ์ปดํฌ๋ํธ์ ๋ถ๋ด์ ์ค์ด๊ณ ๊ด๋ฆฌ ํฌ์ธํธ๋ฅผ ์ผ์ํํ๋ค.
// ch20_bucketlist/store/src/store.js
import { writable } from "svelte/store";
import { initialBuckets } from "./bucketData";
import { v4 as uuidv4 } from "uuid";
const setBucketData = () => {
let initBucketData = {
buckets: initialBuckets,
editMode: ''
}
const { subscribe, update } = writable(initBucketData);
const onToggle = (id) => {
update(datas => { /* ... ์ฒดํฌ ํ ๊ธ ๋ก์ง ... */ });
};
const onRemove = (id) => {
update(datas => { /* ... ์์ดํ
์ญ์ ๋ก์ง ... */ });
};
const onSubmit = (bucketText) => {
update(datas => { /* ... ์ ์์ดํ
์ถ๊ฐ ๋ก์ง ... */ });
};
// ... onEditMode, offEditMode, onEditItem ๋ฑ ๋ค๋ฅธ ํจ์๋ค
// ํ์ํ ๊ธฐ๋ฅ๋ค์ ๊ฐ์ฒด๋ก ๋ฆฌํด
return {
subscribe,
onToggle,
onRemove,
onEditMode,
offEditMode,
onEditItem,
onSubmit
}
}
export const buckets = setBucketData();
setFormBucket
๋ฐ์ดํฐ ์ถ๊ฐ ์ ์ฌ์ฉ๋ ํ ์คํธ ๊ด๋ฆฌ
์๋ก์ด ๋ฒํท์ ์ถ๊ฐํ ๋ ์ฌ์ฉ๋๋ <input>์ ํ ์คํธ ๊ฐ์ ๊ด๋ฆฌํ๊ธฐ ์ํ writable ์คํ ์ด์ด๋ค. ๊ฐ์ ์ด๊ธฐํํ๋ resetForm ๊ฐ์ ์ปค์คํ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์ฌ writable ์คํ ์ด๋ฅผ ํ์ฅํ๋ค.
// ch20_bucketlist/store/src/store.js
const setFormBucket = () => {
const { subscribe, set } = writable('');
const resetFrom = () => set(''); // ๊ฐ์ ์ด๊ธฐํ
return {
subscribe,
set,
resetFrom
}
}
export const bucketText = setFormBucket();
setChkCount
์คํ ์ด๋ก๋ถํฐ ํ์๋ ๋ฐ์ดํฐ(์ฒดํฌ๋ ๊ฐ์) ๊ด๋ฆฌ
derived ์คํ ์ด๋ ๋ค๋ฅธ ์คํ ์ด์ ๊ฐ์ ์์กดํ๋ ์๋ก์ด ๊ฐ์ ๋ง๋๋ ๋ฐ ์ฌ์ฉ๋๋ค. setChkCount๋ buckets ์คํ ์ด๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค, ์๋ฃ๋์ง ์์(chk:false) ํ ์ผ์ ๊ฐ์๋ฅผ ์๋์ผ๋ก ๋ค์ ๊ณ์ฐํ์ฌ ์ ๊ณตํ๋ค. ์ด๋ฅผ ํตํด ํ ์ผ ๊ฐ์๋ฅผ ์๋์ผ๋ก ๊ด๋ฆฌํ ํ์ ์์ด ํญ์ ์ต์ ์ํ๋ฅผ ์ ์งํ ์ ์๋ค.
// ch20_bucketlist/store/src/store.js
import { derived } from "svelte/store";
// ...
const setChkCount = () => {
const count = derived(buckets, $buckets => {
return $buckets.buckets.filter((bucket) => !bucket.chk).length;
});
return count;
}
export const chkCount = setChkCount();
๋ฐ์ดํฐ ํ๋ฆ: ์ปดํฌ๋ํธ-์คํ ์ด ์ํธ์์ฉ
์ปค์คํ
์คํ ์ด๋ฅผ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ ํ๋ฆ์ด ํ๊ฒฐ ๋จ์ํ๊ณ ๋ช
ํํด์ก๋ค.
- ์ฝ๊ธฐ: BucketHeader๋ ๋จ์ ํ ์ผ ๊ฐ์๋ฅผ ํ์ํ๊ธฐ ์ํด chkCount ์คํ ์ด๋ฅผ ๊ตฌ๋ ํ๋ค. Svelte์ $ ๋ฌธ๋ฒ์ ์ฌ์ฉํ์ฌ $chkCount ์ฒ๋ผ ์ ๊ทผํ๋ฉด, ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์ปดํฌ๋ํธ๊ฐ ์๋์ผ๋ก ๋ฆฌ๋ ๋๋ง๋๋ค. BucketList ์ญ์ $buckets.buckets๋ฅผ ๊ตฌ๋ ํ์ฌ ๋ฆฌ์คํธ๋ฅผ ํ๋ฉด์ ๊ทธ๋ฆฐ๋ค.
- ์ฐ๊ธฐ: BucketItem์ ํด์งํต ์์ด์ฝ์ ํด๋ฆญํ๋ฉด, onRemove(bucket.id) ํจ์๊ฐ ํธ์ถ๋๋ค. ์ด ํจ์๋ buckets ์คํ ์ด์์ ๊ฐ์ ธ์จ ๊ฒ์ผ๋ก, ๋ด๋ถ์ ์ผ๋ก update๋ฅผ ์คํํ์ฌ ์คํ ์ด์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ค. ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด, ์ด ์คํ ์ด๋ฅผ ๊ตฌ๋ ํ๊ณ ์๋ BucketList์ BucketHeader๊ฐ ์ฆ์ ์๋ก์ด ์ํ๋ฅผ ๋ฐ์ํ์ฌ ์ ๋ฐ์ดํธ๋๋ค.
์ด๋ ๊ฒ ์ปดํฌ๋ํธ๋ ์คํ ์ด์ ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ํ ๋ณ๊ฒฝ์ ์์ฒญํ๊ณ , ์คํ ์ด๋ ๋ด๋ถ ๋ก์ง์ ๋ฐ๋ผ ์ํ๋ฅผ ์
๋ฐ์ดํฐํ๋ฉฐ, ์ด ์ํ๋ฅผ ๊ตฌ๋
ํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๋ ์๋์ผ๋ก ํ๋ฉด์ ๊ฐฑ์ ํ๋ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ์ด ์์ฑ๋๋ค.
๋์ ์ธ ํ๋ฉด ์ ํ ํจ๊ณผ
์ค๋ฒจํธ์ ๋ด์ฅ ํธ๋์ง์
๊ณผ ์ ๋๋ฉ์ด์
๊ธฐ๋ฅ์ ํ์ฉํ์ฌ ํจ๊ณผ๋ฅผ ์ฃผ์๋ค. ๋ฆฌ์คํธ ์์ดํ
์ด ์ถ๊ฐ๋๊ฑฐ๋, ์ญ์ ๋ ๋ ํจ๊ณผ๋ฅผ ์ ์ฉํ์ฌ ๋ถ๋๋ฝ๊ฒ? ์๋๊ฐ ์๊ฒ ๋ง๋ค์๋ค.
<!-- ch20_bucketlist/store/src/components/BucketList.svelte -->
<script>
import { fade, slide } from "svelte/transition";
import { flip } from "svelte/animate";
// ...
</script>
{#each $buckets.buckets as bucket, index(bucket) }
<div in:fade out:slide animate:flip>
<BucketItem {bucket} />
</div>
{/each}in:fade, out:slide, animate:flip์ ์ฌ์ฉํ์ฌ ๋จ ๋ช์ค๋ง์ผ๋ก ์์ฐ์ค๋ฌ์ด ์ ๋๋ฉ์ด์ ์ด ์์ฑ๋๋ค.

๐ฉ๏ธํ๋ก์ ํธ: Best Tour
My Bucket List์ ์ด์ ๋ ๋ฒ์งธ ํ๋ก์ ํธ. ์ํ ๋ชฉ๋ก์ ๋ณด์ฌ์ฃผ๊ณ , ์ข์์ ๊ธฐ๋ฅ์ ํตํด ์ ํธ๋๋ฅผ ํ์ํ๋ฉฐ ์๋ก์ด ์ฌํ ์ํ์ ์ถ๊ฐํ๊ณ ์ญ์ ํ๋ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ค.
์ด์ ํ๋ก์ ํธ์์ ๋ค๋ค๋ ์คํ ์ด๋ฅผ ์ด์ฉํ ์ํ ๊ด๋ฆฌ๋ฅผ ๋ค์ ํ๋ฒ ์ ์ฉํ๋ฉฐ ์คํ ์ด์ ๋ํ ์ดํด๋ฅผ ํ์ธต ๋์ผ ์ ์์๋ค. ์ด๋ฏธ์ง์ ๋ณตํฉ์ ์ธ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ๋ค๋ค์ ์ข ๋ ์ค์ ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์
๊ฐ๋ฐ์ ํ ๊ฑธ์ ๋ค๊ฐ๊ฐ
์ปดํฌ๋ํธ
์ญ์ UI๋ฅผ ๊ธฐ๋ฅ๋ณ๋ก ๋๋์๋ค.
- Title.svelte: ํ์ด์ง์ ์ ๋ชฉ์ ํ์ํ๋ ์ปดํฌ๋ํธ
- BestList.svelte: ์ ์ฒด ์ฌํ ์ํ ๋ชฉ๋ก์ ํ์ํ๋ ์ปจํ ์ด๋ ์ปดํฌ๋ํธ
- BestCreate.svelte: ์๋ก์ด ์ฌํ ์ํ์ ์ถ๊ฐํ๋ ํผ๊ณผ ๋ฒํผ์ ๋ด์ ์ปดํฌ๋ํธ
// ch21_besttour/complete/src/App.svelte
<script>
import Title from "./components/Title.svelte";
import BestList from "./components/BestList.svelte";
import BestCreate from "./components/BestCreate.svelte";
</script>
<div class="bestbox">
<Title name="BEST TOUR" />
<BestList />
<BestCreate />
</div>
์ปค์คํ ์คํ ์ด
ํ๋ก์ ํธ ํต์ฌ ๋ก์ง์ store.js ํ์ผ์ ์ ์๋ ์ปค์คํ
์คํ ์ด๋ฅผ ํตํด ๊ด๋ฆฌ๋๋ค. ๋ฐ์ดํฐ์ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ๋ ๋ก์ง์ UI๋ก๋ถํฐ ๋ถ๋ฆฌํ์ฌ ์ฝ๋์ ์์ง๋์ ์ฌ์ฌ์ฉ์ฑ์ ๋์๋ค.
setBestData
์ฌํ ์ํ ๋ฐ์ดํฐ, ํต์ฌ ๋ก์ง
writable ์คํ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก, ์ฌํ ์ํ ๋ชฉ๋ก์ ์ด๊ธฐ ๋ฐ์ดํฐ๋ฅผ ์ค์ ํ๊ณ '์ข์์' ํ ๊ธ, ์ํ ์ญ์ , ์ ์ํ ์ถ๊ฐ์ ๊ฐ์ ํต์ฌ์ ์ธ ๋ฐ์ดํฐ ์กฐ์ ํจ์๋ค์ ํจ๊ป ์ ๊ณตํ๋ ์ปค์คํ
์คํ ์ด์ด๋ค.
// ch21_besttour/complete/src/store.js
import { writable } from "svelte/store";
import { initialBests } from './bestData';
import { v4 as uuidv4 } from 'uuid';
const setBestData = () => {
const { subscribe, update } = writable(initialBests);
// '์ข์์' ์ํ๋ฅผ ํ ๊ธํ๋ ํจ์
const onToggle = (id) => {
update(datas => {
const setDatas = datas.map((best) => {
return best.id === id ? { ...best, like: !best.like } : best;
});
return setDatas;
});
};
// ํน์ ์์ดํ
์ ์ญ์ ํ๋ ํจ์
const onRemove = (id) => { /* ...์ญ์ ๋ก์ง... */ };
// ์ ์์ดํ
์ ๋ฆฌ์คํธ์ ์ถ๊ฐํ๋ ํจ์
const onSubmit = (bestTexts) => { /* ...์ถ๊ฐ ๋ก์ง... */ };
return {
subscribe,
onToggle,
onRemove,
onSubmit
};
};
export const bests = setBestData();
setFormBest
์ ๋ ฅ ํผ ๋ฐ์ดํฐ ๊ด๋ฆฌ
์๋ก์ด ์ฌํ ์ํ์ ์ถ๊ฐํ ๋ ์ฌ์ฉ๋๋ ์ฌ๋ฌ ์ ๋ ฅ ํ๋์ ์ํ๋ฅผ ํ๋์ ๊ฐ์ฒด๋ก ๊ด๋ฆฌํ๋ ์ปค์คํ ์คํ ์ด์ด๋ค. ํผ์ ์ด๊ธฐํํ๋ resetFrom ๊ฐ์ ์ ํธ๋ฆฌํฐ ํจ์๋ ํจ๊ป ์ ๊ณตํ์ฌ ํผ ๊ด๋ฆฌ๋ฅผ ์ฉ์ดํ๊ฒ ํ๋ค.
// ch21_besttour/complete/src/store.js
const setFormBest = () => {
let formText = { name: '', price: '', image: '', descript: '' };
const { subscribe, set } = writable(formText);
const resetForm = () => {
set({ name: '', price: '', image: '', descript: '' });
};
return { subscribe, set, resetForm };
};
export const bestTexts = setFormBest();
์คํ ์ด์ ์ปดํฌ๋ํธ ์ํธ์์ฉ
๊ฐ ์ปดํฌ๋ํธ๋ ํ์ํ ์คํ ์ด๋ฅผ ์ง์ ๊ตฌ๋ ํ์ฌ ๋ฐ์ดํฐ์ ์ ๊ทผํ๊ณ , ์คํ ์ด๊ฐ ์ ๊ณตํ๋ ํจ์๋ฅผ ํธ์ถํ์ฌ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ค.
- ๋ฐ์ดํฐ ๊ตฌ๋ ($ ๋ฌธ๋ฒ): BestList.svelte๋ $bests๋ฅผ each ๋ธ๋ก์์ ์ฌ์ฉํ์ฌ ์ฌํ ์ํ ๋ชฉ๋ก์ ๋ฐ๋ณต ๋ ๋๋งํ๊ณ , BestCreate.svelte๋ $bestTexts๋ฅผ ๊ฐ input์ bind:valueํ์ฌ ์๋ฐฉํฅ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ์ ๊ตฌํํ๋ค.
- ์ก์ ํธ์ถ: BestItem.svelte์ ์ข์์ ๋ฒํผ์ on:Click={()=>onToggle(id)}์ ๊ฐ์ด bests ์คํ ์ด์์ ๊ฐ์ ธ์จ onToggle ํจ์๋ฅผ ์ง์ ํธ์ถํ๋ค. ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด $bests๋ฅผ ๊ตฌ๋ ํ๋ BestList ์ปดํฌ๋ํธ๊ฐ ์๋์ผ๋ก ์ ๋ฐ์ดํธ๋์ด ๋ณ๊ฒฝ์ฌํญ์ด ํ๋ฉด์ ์ฆ์ ๋ฐ์๋๋ค.
<!-- ch21_besttour/complete/src/components/BestItem.svelte -->
<script>
import { bests } from '../store';
// ...
const { onToggle, onRemove } = bests;
</script>
<li>
<a href="#!">
<img src={image} alt={name} />
<button class="likebox" on:click={() => onToggle(id)}>
<!-- ... -->
</button>
<!-- ... -->
</a>
</li>
๐๋๋์
ํ๋ก์ ํธ๋ฅผ ํ๋ฉด์ Svelte์ ๊ฐ๋ฐ ๋ฐฉ์์ ์ต์ํด์ง ์ ์์๋ค. React์ ์ต์ํ๊ธฐ ๋๋ฌธ์ ๋์ผํ ์ ํ๋ฆฌ์ผ์ด์
์ React๋ก ๊ตฌํํ๋ ์ํฉ์ ๊ฐ์ ํ๋ฉด์ ๋น๊ตํด๋ณด๋ Svelte๋ง์ ์ฅ์ ๋ค์ด ๋ ๋ช
ํํ๊ฒ ๋๊ปด์ง๋ ๋ฏ ํ๋ค.
1. ์ํ๊ด๋ฆฌ: React์์๋ ์ํ์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์๋ค์ Props๋ก ๊ณ์ํด์ ๋ด๋ ค๋ณด๋ด์ผ ํ์ง๋ง, Svelte์์๋ ์คํ ์ด๋ฅผ ๋ง๋ค์ด์ ํ์ํ ์ปดํฌ๋ํธ์์ ๋ฐ๋ก ๋ถ๋ฌ ์ฌ์ฉํ ์ ์์๋ค. props drilling์ ์์ฒ์ ์ผ๋ก ์ฐจ๋จํ๊ณ , ์ปดํฌ๋ํธ๋ค์ด ์ํ ๋ก์ง์ผ๋ก๋ถํฐ ๋
๋ฆฝ๋์ด ํจ์ฌ ๊น๋ํ๋ค๊ณ ๋๊ผ๋ค. ๋ฌผ๋ฐ React์์๋ useReducer๋ Context๋ก ์ํ๊ด๋ฆฌ๋ฅผ ํ ์ ์๊ธด ํ์ง๋ง, ์ค๋ฒจํธ Store๊ฐ ๋ ์ง๊ด์ ์ผ๋ก ๋๊ปด์ก๋ค.
2. ๋ฐ์์ฑ: ์ค๋ฒจํธ์์๋ ์คํ ์ด ์์ $ ๊ธฐํธ๋ฅผ ๋ถ์ด๋ ๊ฒ๋ง์ผ๋ก๋ ๊ฐ์ ๋ณํ๋ฅผ ๊ตฌ๋
ํ๊ณ ํ๋ฉด์ ์๋์ผ๋ก ๊ฐฑ์ ํ ์ ์๋ค. React์์ useEffect๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ์ํ ๋ณํ๋ฅผ ๊ฐ์งํ๊ณ ๋ถ์ ํจ๊ณผ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๊ฐ๋จํ๋ค๊ณ ๋๊ผ๋ค. ์ฝ๋์ ์์ด ์ค์ด๋ค ๋ฟ๋ง ์๋๋ผ, ์ด ๊ฐ์ด ๋ฐ๋๋ฉด ์ด ๋ถ๋ถ๋ ๋ฐ๋๋ค๋ ๊ด๊ณ๊ฐ ๋ช
ํํ๊ฒ ๋๋ฌ๋ฌ๋ค.
3. ๊ฐ๊ฒฐํ ์ปดํฌ๋ํธ ๊ตฌ์กฐ: ์ค๋ฒจํธ์์๋ <script>, <style> ๋งํฌ์
์ด ํ ํ์ผ ์์ ๊ณต์กดํ๋ ๊ตฌ์กฐ ๋๋ถ์ ์ปดํฌ๋ํธ์ ๋ชจ๋ ์ฝ๋๋ฅผ ํ ๋์ ํ์
ํ๊ธฐ ์ฌ์ ๋ค. ๋ํ ์ํ ๊ด๋ฆฌ ๋ก์ง์ Store๋ก ๋ถ๋ฆฌํ๋ฉด์ UI ์ปดํฌ๋ํธ๋ค์ ์ค์ง ํ๋ฉด์ ๊ทธ๋ฆฌ๋ ์ฑ
์์๋ง ์ง์คํ ์ ์์๋ค. React์๋ค๋ฉด ์ํ ๋ก์ง์ ํ์ด ์ปดํฌ๋ํธ๊ฐ ํจ์ฌ ๋น๋ํด์ก์ ๊ฒ. Svelte๋ฅผ ์ฐ๋ ์ปดํฌ๋ํธ๊ฐ ๊ฐ๋ณ๊ฒ ๋๊ปด์ง๋ ๋ฏ ํ๋ค.
ํ๋ก์ ํธ๋ฅผ ํตํด ์ค๋ฒจํธ์ ํต์ฌ ๋ฌธ๋ฒ์ ๊ฒฝํํด๋ณผ ์ ์์๋ค. ์ปดํฌ๋ํธ ๊ตฌ์ฑ๋ถํฐ props, store๋ฅผ ์ฌ์ฉํ ์ํ ๊ด๋ฆฌ, ๊ทธ๋ฆฌ๊ณ ํธ๋์ง์
์ผ๋ก ํจ๊ณผ๊น์ง ๋จ๊ณ๋ณ๋ก ๊ธฐ๋ฅ์ ๊ตฌํํ๋ฉด์ ์ด์ ํ์ต์์๋ ๊ฒฝํํ ์ ์์๋ ๋ฌธ๋ฒ ํ์ฉ๊ณผ Svelte ์ฑ ํ๋ฆ์ ์ ์ ์์๋ค. Svelte๊ฐ ์ ๊ณตํ๋ ๊ฐ๋ฐ ํธ์์ฑ๊ณผ ์ฌ๋ฏธ๋ฅผ ์ ๋๋ก ๋๋ ์ ์์๋ ํ์ต์ด์์!
