관리 메뉴

웹개발자의 기지개

[Svelte] 반응성 변수, 반응성 조건문 본문

javascript/Svelte

[Svelte] 반응성 변수, 반응성 조건문

웹개발자 워니 2025. 8. 13. 20:37

 

React 에는 없는 반응성 변수, 반응성 조건문이 스벨트에서는 코드량을 더욱 단순하고 간편하게 한다.

 

(1)  반응성 변수 - ( 변수에 값만 다시 넣으면 )  단순 대입만하면 화면이 업데이트 된다. 

 

1
2
3
4
5
6
7
8
<script>
  let count = 0;            // 반응성 변수 (상태)
  function inc() {
    count += 1;             // 대입이 발생 → 스벨트가 감지 → 화면 갱신
  }
</script>
 
<button on:click={inc}>Clicked {count} times</button>
cs

 

 

(2)  반응성 선언 ($: ) , 반응성 조건문

 

 

1
2
3
4
5
6
7
8
9
<script>
  let price = 10000;
  let qty = 2;
 
  // price나 qty가 바뀌면 총액(total)을 자동 재계산
  $: total = price * qty; 
</script>
 
<p>총액: {total.toLocaleString()}원</p>
cs

 

 

1
2
3
4
5
6
7
8
9
10
11
12
<script>
  let keyword = '';
 
  // keyword가 바뀔 때마다 콘솔 출력 (부수효과)
  $: console.log('검색어:', keyword);
 
  // 조건부 부수효과: 너무 긴 키워드는 잘라주기
  $: if (keyword.length > 20) {
    keyword = keyword.slice(020);
  }
</script>
 
cs

 

 

 

특정 값이 바뀔 때마다 로그를 찍거나, fetch를 하거나, 타이머를 재설정하는 등 “DOM이 아닌 JS 동작”을 하고 싶을 때

 

 

 

(비교 cf)  {#if} (템플릿 조건문)

 

1
2
3
4
5
6
7
8
9
10
11
<script>
  let count = 0;
</script>
 
<button on:click={() => count++}>+</button>
 
{#if count % 2 === 0}
  <p>짝수입니다.</p>
{:else}
  <p>홀수입니다.</p>
{/if}
cs

 

 

{#if}는 DOM 요소를 붙였다 떼는 일을 한다.
반대로 $: if (...) { ... }는 화면이 아니라 스크립트 동작을 조건부로 실행한다.

 

 

(예제1) 검색어에 따라 리스트 자동 필터링

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
  let query = '';
  let items = ['svelte''solid''react''vue'];
 
  // query나 items가 바뀌면 자동 재계산
  $: filtered = items.filter(v => v.includes(query.toLowerCase()));
</script>
 
<input bind:value={query} placeholder="검색..." />
<ul>
  {#if filtered.length === 0}
    <li>결과 없음</li>
  {:else}
    {#each filtered as name}
      <li>{name}</li>
    {/each}
  {/if}
</ul>
cs

 

 

query가 바뀔 때마다 $:가 filtered를 자동으로 갱신.
화면은 {#if}/{#each}로 렌더링 제어.

 

 

(예제2) ID가 바뀔 때마다 자동으로 데이터 가져오기

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<script>
  let userId = 1;
  let user = null;
  let loading = false;
  let error = null;
 
  // userId가 바뀌면 자동으로 fetch (IIFE 형태)
  $: if (userId) {
    (async () => {
      loading = true; error = null; user = null;
      try {
        const res = await fetch(`/api/users/${userId}`);
        if (!res.ok) throw new Error('네트워크 오류');
        user = await res.json();
      } catch (e) {
        error = e.message;
      } finally {
        loading = false;
      }
    })();
  }
</script>
 
<label>
  User ID:
  <input type="number" bind:value={userId} min="1">
</label>
 
{#if loading}
  <p>불러오는 중...</p>
{:else if error}
  <p style="color:red">{error}</p>
{:else if user}
  <p>{user.name/ {user.email}</p>
{/if}
 
cs

 

데이터 가져오기(부수효과)는 $:
화면 표시 로직은 {#if} 로 분리 → 역할이 명확하고 테스트/유지보수 용이

 

 

*  자주 하는 실수 & 팁

 

1.배열/객체 변경 후 재대입 잊음

user.name = 'Kim';  // ❌ 화면 안 바뀔 수 있음
user = { ...user, name: 'Kim' }; // ✅ 재대입으로 반응성 트리거


2.파생값을 “따로 state로 저장”하려고 함
→ 불필요한 중복 상태, 동기화 버그의 원인. 파생값은 $:로 계산하자.

3.DOM 제어를 $:로 하려고 함
→ DOM은 {#if}, {#each}, {#await} 같은 템플릿 블록으로 제어하자.

4.복잡한 비동기 로직을 이벤트 핸들러에만 몰아넣음
→ 의존 값 변화에 자동 반응하려면 $:를 활용해 데이터 흐름을 선언적으로 만든다.

 

 

 

[ 정리하기 ]

 

반응성 변수: 최상위 let에 대입만 하면 화면이 갱신된다.

$:: 값이 바뀔 때마다 JS 계산/부수효과를 다시 실행한다. (파생값/로그/fetch 등)

{#if}: 화면 렌더링(보이고/숨기기) 을 제어한다.

 

 

 

 

 

 

 

 

'javascript > Svelte' 카테고리의 다른 글

[Svelte] Svelte 익히기  (0) 2025.08.06
Comments