Svelte 논리 블록

·2024년 10월 20일
0

Svelte

목록 보기
5/7
post-thumbnail

🎵 들어가며

이번 포스팅에서는 스벨트에서 사용하는 논리 블록에 대해 알아보자! 😀


🎵 논리 블록

🔮 조건문 블록

스벨트는 조건에 따라 DOM을 화면에 나타낼지 나타내지 않을지 선택할 수 있는 조건문 블록을 제공한다. js와 동일하게 If, Else, Else-if 블록이 있다.

If 블록

<script>
	let user = {loggedIn: false};

	function toggle() {
		user.loggedIn = !user.loggedIn;
	}
</script>

{#if user.loggedIn}
	<button on:click={toggle}>
		Log out
	</button>
{/if}

{#if !user.loggedIn}
	<button on:click={toggle}>
		Log in
	</button>
{/if}

Else 블록

Else 블록을 사용하여 좀 더 간단히 작성해 보자.

<script>
	let user = {loggedIn: false};

	function toggle() {
		user.loggedIn = !user.loggedIn;
	}
</script>

{#if user.loggedIn}
	<button on:click={toggle}>
		Log out
	</button>
{:else}
	<button on:click={toggle}>
		Log in
	</button>
{/if}

Else-if 블록

<script>
	let x = 7;
</script>

{#if x > 10}
	<p>{x} is greater than 10</p>
{:else if 5 > x}
	<p>{x} is less than 5</p>
{:else}
	<p>{x} is between 5 and 10</p>
{/if}

🔮 반복문 블록

Each 블록

배열

<script>
	const arr = ['H', 'e', 'l', 'l', 'o'];
</script>

<ul>
	{#each arr as item}
		<li>{item}</li>
	{/each}
</ul>

유사 배열

<script>
	const arrLike = {
		0: 'H',
		1: 'e',
		2: 'l',
		3: 'l',
		4: 'o',
		length: 5
	};
</script>

<ul>
	{#each arrLike as item}
		<li>{item}</li>
	{/each}
</ul>

iterable 객체

반복 가능한 객체는 아래와 같이 Each 블록을 사용할 수 있다.

  • iterator
    value와 done이라는 두 개의 속성을 가진 객체를 반환하는 next 함수를 포함한 객체
  • iterable
    이터레이터를 반환하는 [Symbol.Iterator] 함수를 가진 객체
<script>
	const iterable = {
		[Symbol.iterator]: function*() {
			yield 'H';
			yield 'e';
			yield 'l';
			yield 'l';
			yield 'o';
		}
	};
</script>

<ul>
	{#each [...iterable] as item}
		<li>{item}</li>
	{/each}
</ul>

Else 블록

Each 블록의 배열이 비어 있을 경우, 예외 처리 표현을 위해 Else 블록을 사용할 수 있다.

<script>
	let arr = [];
	setTimeout(()=>{
		arr = ['H', 'e', 'l', 'l', 'o'];
	}, 1000)
</script>

<ul>
	{#each arr as item}
		<li>{item}</li>
	{:else}
		<li>빈 배열입니다.</li>
	{/each}
</ul>

index 사용

Each 블록의 두 번째 파라미터로 현재의 index를 알 수 있다.

<script>
	const arr = ['H', 'e', 'l', 'l', 'o'];
</script>

<ul>
	{#each arr as item, i}
		<li>{i+1}: {item}</li>
	{/each}
</ul>

구조 분해 사용

<script>
	const arr = [
		{id: 1, value: 'H'},
		{id: 2, value: 'e'},
		{id: 3, value: 'l'},
		{id: 4, value: 'l'},
		{id: 5, value: 'o'}
	];
</script>

<ul>
	{#each arr as {id, value}}
		<li>{id}: {value}</li>
	{/each}
</ul>

Key 지정

Key는 Each 블록의 업데이트를 최적화하기 위해 사용된다. Key를 지정하면 업데이트되었을 때, 업데이트된 위치를 정확히 인지해 해당 DOM만 업데이트할 수 있다.

<script>
	let arr = [
		{id: 1, value: 'H'},
		{id: 2, value: 'e'},
		{id: 3, value: 'l'},
		{id: 4, value: 'l'},
		{id: 5, value: 'o'}
	];
</script>

<ul>
	{#each arr as item}
		<li>{item.id}: {item.value}</li>
	{/each}
</ul>

<button on:click={() => {arr = arr.slice(1)}}>
	첫 번째 아이템 제거
</button>

위와 같이 작성했을 경우, 첫 번째 아이템이 제거되면 위에서부터 순차적으로 업데이트가 되고 마지막 아이템이 삭제되어 총 5번의 업데이트가 발생한다.

<script>
	let arr = [
		{id: 1, value: 'H'},
		{id: 2, value: 'e'},
		{id: 3, value: 'l'},
		{id: 4, value: 'l'},
		{id: 5, value: 'o'}
	];
</script>

<ul>
	{#each arr as item (item.id)}
		<li>{item.id}: {item.value}</li>
	{/each}
</ul>

<button on:click={() => {arr = arr.slice(1)}}>
	첫 번째 아이템 제거
</button>

두 번째 코드처럼 Key를 지정하면 실제로 변경된 아이템만 업데이트되어 최적화된다. Key를 지정하는 방법은 {#each arr as item (item.id)}와 같이 소괄호({...}) 안에 Key를 지정하면 된다.

스벨트는 내부적으로 Map 객체를 사용하기 때문에 Key에 숫자나 문자열뿐만 아니라 객체를 사용할 수도 있다. 즉, (item.id) 대신 (item)으로 변경할 수도 있다!


🔮 비동기 블록

Await 블록

<script>
	let promise = getRandomNumber();

	function getRandomNumber() {
		return new Promise((resolve, reject) => {
			setTimeout(() => {
				resolve(Math.random());
			}, 2000);
		});
	}

	function handleClick() {
		promise = getRandomNumber();
	}
</script>

{#await promise}
	<p>기다리는 중...</p>
{:then number} 
	<p>생성된 숫자는 {number}입니다.</p>
{:catch error}
	<p style="color: red">{error}</p>
{/await}

<button on:click={handleClick}>생성하기</button>

{#await promise}...{:then number}

비동기 작업이 응답하기 전 화면에 노출되는 블록이다. 스켈레톤 UI를 사용하기 적당한 블록이다.

{:then number}...{:catch error}

비동기 작업이 응답하여 응답된 결과가 화면에 노출되는 블록이다. number는 Promise의 resolve 함수에 전달된 파라미터 값이다. Async 함수의 경우에는 반환값이다.

{:catch error}...{/await}

비동기 작업에서 에러가 발생할 때 화면에 노출되는 블록이다. error는 Promise의 reject 함수에 전달된 파라미터 값이다. Async 함수의 경우에는 throw로 반환된 값이다.

간략한 Await 블록

{#await promise then number}
	<p>생성된 숫자는 {number}입니다.</p>
{/await}

비동기 작업에서 에러가 발생하지 않을 것을 확신할 수 있다면 Catch 블록을 생략할 수 있다.


🔮 Key 블록

Key 블록을 사용하면 블록에 사용한 표현식이 업데이트되면서 Key 블록의 내용들이 제거된 후 다시 추가된다.

<script>
	import KeyComp from './KeyComp.svelte';
	let value = 0;
</script>

{#key value}
	<KeyComp {value} />
{/key}
<button on:click={() => value++}>Add Value</button>

완성 화면

개발자 도구로 살펴보면 첫 렌더링 시 컴포넌트가 생성되어 create 로그가 출력된 것을 볼 수 있다. Key 블록의 조건이 업데이트될 때마다 컴포넌트가 제거된 후 다시 생성된다. 때문에 Add Value 버튼이 클릭된 횟수만큼 로그가 출력된다.

profile
풀스택 개발자 기록집 📁

0개의 댓글