Svelte TIL 04

18887 단어 sveltesvelte

참고

Svelte.js 완벽 가이드 - HEROPY


@html

<!-- [코드 4-1] App.svelte-->
<script>
  let h1 = '<h1>hello world</h1>';
</script>
{@html h1}

@html 키워드를 통해 문자열 내부를 html으로 평가하여 보여준다. xss의 위험이 있으므로 문자열을 적절히 필터링하는 전처리가 필요하다.

@debug

<!-- [코드 4-2] App.svelte-->
<script>
  let cnt = 0;
</script>

{@debug cnt}
<button on:click={ () => cnt++ }>up</button>

cnt값이 바뀔 때 마다 cnt의 값을 console.log() 없이도 개발자도구에 출력해준다. 개발자도구가 닫혀있다면 console탭에 로그가 쌓이기만 한다. 만약 개발자 도구가 켜있다며 로그가 쌓임과 동시에 코드가 일시정지된다.

데이터의 불변성과 가변성

JS의 원시데이터(숫자, 문자열, null, symbol, undefined 등)는 Immutable하다.(불변성) 한 번 메모리에 할당되면 변경될 수 없다. 원시데이터를 값으로 갖는 변수에 새 값이 할당된다면, 새로운 번지에 데이터를 할당 한 뒤 변수가 가리키는 번지를 변경한다.

객체(Object, Array 등)는 Mutable하다.(가변성) 메모리에 할당되었더라도 변경될 수 있다.

할당과 반응성

<!-- [코드 4-3] App.svelte-->
<script>
  let arr = ['x', 'y'];
  let obj = {
    a : 123,
    b : [1, 2],
  };

  function assign() {
    arr.push('z');
    obj.a = 456;
    obj.b.push(3);
  }
</script>

<button on:click={assign}>assign</button>
<h1>{arr}</h1>
<h1>{obj.a}</h1>
<h1>{obj.b}</h1>

위 코드에서 버튼을 누르면 arr는 값이 그대로이고, obj.a와 obj.b의 값만 변화한다.

  • arr.push('z')는 대입연산이 없었으므로 반응성을 갖지 않는다. 아래 [코드 4-4]에서 해결해보자.
  • obj.a = 456은 새 값이 대입되었으므로 반응성을 갖는다.
  • obj.b.push(3)은 arr와 사실상 동일한 코드이지만, 이상하게도 반응성을 가졌다. [코드 4-5]에서 다시 살펴보자.
<!-- [코드 4-4] App.svelte-->
<script>
  let arr = ['x', 'y'];

  function assign_1() {
    arr = [...arr, 'z'];
  }
  function assign_2() {
    arr.push('z');
    arr = arr;
  }
</script>

<button on:click={assign_1}>assign_1</button>
<button on:click={assign_2}>assign_2</button>
<h1>{arr}</h1>

arr에 하여금 반응성을 갖도록 하는 방법 두 가지를 작성했다. 둘 모두 대입연산을 포함한다는 공통점을 갖고있다.

<!-- [코드 4-5] App.svelte-->
<script>
	let obj = {
		a : 123,
		b : [1, 2],
	};

	function change_a_and_b() {
		obj.a = 456;
		obj.b.push(3);
	}
    function change_only_b() {
		obj.b.push(3);
	}
</script>

<button on:click={change_a_and_b}>a and b</button>
<button on:click={change_only_b}>b</button>
<h1>{obj.a}</h1>
<h1>{obj.b}</h1>

문제의 obj.b.push(3)을 살펴보자. change_a_and_b를 실행하면 obj.b가 반응성을 갖는다. 그러나 change_only_b를 실행하면 obj.b가 반응성을 갖지 못한다.

TIL 03 포스트에서 살펴본 바와 같이, 대입과 동시에 Re-render가 일어나는 것이 아니라 일정 단위로 Re-render가 일어난다. change_a_and_b()를 통해obj.a = 456이 실행되면 svelte는 obj.a뿐 아니라 obj전체를 갱신한다. 그 시점에서는 obj.aobj.b모두 값이 바뀌었으므로 화면으로 볼 때에는 둘 모두 Re-render된다. obj.b는 영문도 모른채 obj.a덕분에 반응성을 갖게 된 것이다.

반응성 구문

개요

<!-- [코드 4-6] App.svelte-->
<script>
	let text = 'a';
	let doubleText;
	
	$ : {
	  doubleText = text + text;
	  console.log(doubleText.length, doubleText);
	}
  </script>
  <h1 on:click={()=>{text=text+'a';}}>{text.length}{text}</h1>

$라는 이름의 label구문에 포함된 어떤 변수가 반응성을 가질 때, 해당 label구문을 실행한다.
반응성 구문의 trigger가 되는 변수가 label구문 안으로 몇depth를 들어가는지는(어떤 scope를 갖는지) 상관없다.

일반형

let doubleText;
$ : { 
  doubleText = text + text;
}

축약형

$ : doubleText = text + text;

블록없이 콜론 :뒤에 바로 변수명을 명시하면, 별도 선언없이 doubleText 변수를 만든다. doubleTexttext의 반응성에 뒤이어 반응성을 갖는다.

함수실행

$: text, (()=>{console.log(text);})

조건문/반복문

$: if(text==='aaaa'){console.log(text);}
$: for(let i=0; i<10; i++){
  text;
  console.log(i);
}

좋은 웹페이지 즐겨찾기