실무에 SvelteKit 조지면서 꼼수부리는 팁을 공유한다.
닥치고 내말 듣고 따라해봐라.

반응형 Promise

{#await} 블록은 Promise 를 갖다 쓸 수 있는 블록으로, 리액트나 뷰에서 보기 힘든 공식적인 비동기 처리 블록이라고 보면 된다.
초기화를 할 때 이렇게 하기 십상인데,

let myPromise

const doSomething = () => {
  myPromise = fetch('/path/to/api').then(res => res.json())
}

이렇게 하면 {#await} 블록은 쌩 까고 바로 {:then} 블록 내용이 뜰 것이다.
이유는 간단한데, 초기화 시 당연히 undefined 기 때문에 스벨트 컴파일러는 이를 Promise.resolve(undefined) 로 인지하고 처리한다.
만약, 초기 상태, 즉, 로딩 이미지 등을 뿌리든가 이런 내용을 표현하고 싶다면,
그냥 기약 없는 약속을 초기화 시켜주면 된다.

let myPromise = new Promise(() => {})

그러면 진짜 약속으로 바꾸기 전까지는 세월아~ 네월아~ {#await} 블록에 정의한 화면, 예를 들면 로딩 화면이 영원히 렌더링 될 것이다.

반응형 대상 변수 필터링

스벨트의 반응 구문(Reactive Statement)과 비슷한 리액트의 useEffect 함수가 있는데,
useEffect 함수의 두번째 인자는, 반응할 대상을 지정할 수 있다는 점이 있겠다.
이를 통해 필요한 반응에만 재렌더링 하는 기능이 있는데, 스벨트는 그딴거 없다.
대신 스벨트는 반응 구문 작성 시, 그 구문 안에 있는 반응형 변수가 반응할 경우에만 작동한다.
두번째 인자 지정 안 할 경우 자비없이 그냥 뭐만 바뀌었다 하면 무작정 렌더링 더럽게 해버리는 useEffect 함수에 비하면 자애롭다.
하지만 대신, 스벨트는 반응할 변수를 선택할 수가 없다.
대신 꼼수를 쓸 수 있는데, 반응 구문 안에 있는 반응 변수에만 반응하기 때문에, 필요한 반응 변수만 구문에 넣고 나머지는 함수로 빼면 된다.

예를 들어보자.

let one, two, three
$: {
  doSomething(one, two)
}

이렇게 작성하면 doSomething 함수는 onetwo 변수의 변경이 일어날 때만 호출한다.
하지만 난 one 변수의 변경이 일어날 때만 호출하고 싶다면? 이걸 회피하도록 해보자.

let one, two, three
const doSomethingReactive = (..._) => {
  doSomething(one, two)
}
$: {
  doSomethingReactive(one)
}

이렇게 하면, one 변수의 변경이 일어날 때만 onetwo 변수를 참조하여 doSomething 함수를 호출하게 된다.
물론 회피 방법은 다양하니 적절하게 활용하도록 하자.

재활용 가능한 반응형 구문

리액트의 useEffect 함수는, 첫번째 인자에 함수를 작성하고, 리턴값에 함수를 작성할 수 있는데,
리턴값에 집어넣는 함수는, 버릴 작업에 대한 함수를 작성할 수 있다.
즉, 스벨트의 use:action 속성에 넣을 함수의 리턴값 중 destroy 함수 정의에 해당하는 기능이다.
물론 use:action 속성을 사용할 수 있지만, useEffect 함수를 흉내낼 수 있다.

어떻게? 이렇게.

export const useEffect = subscribe => ({ subscribe })

구현은 이렇게 하면 된다.

let effect
$: effect = useEffect(() => {
  const clickEvent = e => console.log('Clicked at ' + e.target.id)
  node.addEventListener('click', clickEvent)
  return () => {
    node.removeEventListener('click', clickEvent)
  }
})

$: $effect // 잊지말자!

이 때, $effect 를 반응 구문에 추가하여 subscribe 로 정의한 함수가 작동하도록 유도해야 한다.
마지막 줄 추가 안하면 작동 안되고 해매는 너 자신을 발견할 수 있다.
뭐? 변수에 달러 붙이는 건 writablereadable 같은 특수한 상황에서만 가능하다고?
아니, 스벨트는 굳이 그렇게 똑똑하게 안 한다. 그저 해당 변수 및 상수의 subscribe 멤버 함수만 있으면 동작 잘만 한다.
즉, RxJS 에서 구현한 Observable 객체도 먹히는 등, 스벨트 자체에서 Observable 인터페이스를 구현했다는 소리가 된다.

오랜만에 기술적 팁을 내니 어색하지?
나도 어색하다.
뭐? 스벨트 안쓰고 리액트나 뷰 쓴다고?
그래 즐거운 시간 보내~

끗.

profile
지옥에서 온 개발자

0개의 댓글