가장 빨리 만나는 스벨트 | 5장 ~ 10장
반응성(reactivity)
반응성이란 관심있는 무언가에 반응하여 동작하는 것을 말합니다.
인터넷 브라우저의 크기에 반응하여 그에 맞는 페이지 형태를 보여주는 것을 리액티브 웹(reactive web)이라고 합니다. 이렇게 무언가에 반응하여 동작하는 것에 대하여 "리액티브하다" 또는 "반응형이다"라고 말합니다.
스벨트에서는 컴포넌트의 스크립트 블록 안에서 선언한 배열, 객체, 문자열 및 숫자 변수 모두 반응성을 가집니다. 센서의 감지 대상을 반응형 데이터(reactive data), 또는 반응형 변수라고 부릅니다. 센서 동작의 트리거에 해당하는 것이 스벨트에서는 할당(assignment)입니다. 할당은 연산자(=)을 사용하여 반응형 데이터에 값을 변경하면 그만입니다.
트리거가 일어나면 센서가 감지하고 동작이 수반됩니다. 트리거에 수반되는 동작을 스벨트에서는 코드로 정의합니다. 이 코드를 반응형 상태(reactive statement) 코드라고 합니다.
바인딩 줄여쓰기
전체 바인딩 구문이 bind:paused={paused} 처럼 HTML 엘리먼트의 속성명과 스크립트 블록의 변수명이 같으면 생략하여 bind:속성명 형태로 중괄호 없이 짧게 줄여 쓸 수 있습니다.
비디오 제어 애플리케이션 만들기
책에서 제공하는 예제로 비디오 애플리케이션을 만들었다. 만들면서 느낀 것은 양방향 데이터바인딩을 통해 코드를 엄청 줄일 수 있다는 것이다.
<script>
let paused = true;
let currentTime = 0;
let duration
let volume = 0.5
let muted = false
let playbackRate = 1
</script>
<video src="https://ppillip.github.io/github.io/unity2d.mp4"
bind:paused
bind:currentTime
bind:duration
bind:volume
bind:muted
bind:playbackRate
>
<track kind="captions"/>
</video>
<div>
<input class="progress" type="range" bind:value={currentTime} min=0 max={duration} step=0.001/>
<div class="item">
<span>{currentTime}</span>
<span>{duration}</span>
</div>
<br/>
<div class="controls">
<button on:click={() => {paused = !paused}}>
{#if paused} 시작
{:else} 정지 {/if}
</button>
<select bind:value={playbackRate}>
<option value={0.25}>0.25배속</option>
<option value={0.5}>0.5배속</option>
<option value={0.75}>0.75배속</option>
<option value={1}>1배속</option>
<option value={2}>2배속</option>
<option value={3}>3배속</option>
</select>
<button on:click={() => currentTime = currentTime - 5}>< 5초</button>
<button on:click={() => currentTime = currentTime + 5}>> 5초</button>
<button on:click={() => muted = !muted}>
{#if muted} 소리 켜기
{:else} 소리 끄기 {/if}
</button>
<input type="range" bind:value={volume} min=0 max=1 step=0.01/> 볼륨: {volume}
</div>
</div>
라이프 사이클
컴포넌트는 다른 컴포넌트에 의해서 돔에 추가되고 사용됩니다. 컴포넌트는 여러 가지 조건에 따라 업데이트되거나 돔에서 제거되기도 합니다. 개발자는 이런 변화의 시점마다 제어해야 합니다. 라이프 사이클 함수는 콜백 함수를 인자로 받아 각각 특성에 맞게 콜백 함수를 실행합니다. 라이프 사이클 함수는 다음과 같습니다.
- onMount: 컴포넌트 인스턴스가 생성되어 돔에 추가될 때 입력받은 콜백 함수를 호출합니다.
- beforeUpdate: 컴포넌트가 돔에 업데이트되기 직전에 입력받은 콜백 함수를 호출합니다.
- afterUpdate: 돔에 업데이트 직후 입력받은 콜백 함수를 호출합니다.
- onDestroy: 컴포넌트가 돔에서 제거될 때 마지막으로 콜백 함수를 호출합니다.
onMount 함수는 컴포넌트가 돔에 렌더링되고 컴포넌트가동작 준비가 완료되었을 때 한 번만 호출합니다. onDestry 콜백 안에서는 서버와 연결된 소켓을 끊거나 onMount 콜백안에서 할당 받은 리소스를 해제하는 구문들이 들어가면 좋습니다.
특히 컴포넌트가 최초 돔에 렌더링이 끝나고 사용자에 이벤트에 의해 돔이 변경이 일어날 때, 이 시점에 개입하여 처리가 필요하다면 beforeupdate 함수나 afterupdate 함수를 이용하여 처리하면 유용합니다.
그런데 라이프사이클 함수는 독립적이고 선언적으로 사용해서 우리가 원하는 코드안에서 호출할 수가 없습니다. 만약에 사용자 이벤트를 처리하는 함수나 우리가 작성할 함수 안에서 비슷한 처리가 필요할 때 tick 함수를 사용합니다. tick 함수를 사용하면 스벨트가 돔 업데이트가 끝나고 tick 함수가 종료되어 값을 잘 반영할 수 있습니다. 다만 컴포넌트 초기화 시점에 호출되어야하는 일반 라이프사이클 함수와 다르게 필요한 시점에 사용할 수 있습니다.