Svelte

[Svelte]DOM 적용 후 실행되는 tick 함수

DevStory 2022. 8. 8.

tick 함수

svelte에서 제공하는 tick() 함수는 props 또는 state가 DOM에 적용되자마자 Promise 객체를 반환합니다.

 

쉽게 설명하자면, script 영역에 선언된 변수의 값이 변경된 후 컴포넌트 또는 DOM 요소가 DOM에 바로 적용되지 않습니다. 추가적으로 처리해야 하는 작업이 필요한지 체크 및 적용 후 DOM에 적용합니다.

 

따라서, 추가적으로 처리해야 하는 작업이 필요한지 체크하는 과정에서 DOM 요소를 접근하는 경우 여러 문제가 발생합니다.

 

예를 들어, 다음과 같이 "input 태그 활성화" 버튼을 클릭하면 조건문에 의해 input 태그가 활성화됩니다. input 태그 활성화됨과 동시에 input 태그와 바인딩된 변수를 사용하여 포커싱 처리하려고 했으나 TypeError가 발생합니다.

<script>
  let strValue = '';    
  let isInputElementView = false;
  let inputBind;

  const handleClick = (param) => {
    isInputElementView = param;
    if(isInputElementView === true) {
      inputBind.focus();
    }
  }
</script>

<button on:click={() => handleClick(true)}>
  input 태그 활성화
</button>

<button on:click={() => handleClick(false)}>
  input 태그 비활성화
</button>

{#if isInputElementView}
<div>
  <input type="text" bind:value={strValue} bind:this={inputBind} />
</div>
{/if}

[실행 결과]

TypeError가 발생하는 이유는 변수 isInputElementView의 값이 true로 갱신되었지만, DOM에 input 태그가 바로 반영되지 않았기 때문에 바인딩 변수로 input 태그를 접근할 수 없습니다.


예제 1. tick() 함수 사용

위 문제를 해결하는 방법으로 use 지시자 또는 생명주기 함수인 onMount() 함수를 사용할 수 있지만, 이번 포스팅은 tick() 함수에 대해 소개하므로 tick() 함수를 사용하여 해결합니다.

 

"input 태그 활성화" 버튼과 "input 태그 비활성화" 버튼을 클릭하면, 호출되는 이벤트 핸들러 함수인 handleClick()에서 tick() 함수를 호출합니다.

 

tick() 함수는 컴포넌트 또는 DOM 요소가 DOM에 적용되자마자 Promise 객체를 반환합니다. 정상적으로 이행되었을 때, 처리해야 하는 작업을 then() 함수의 콜백 함수로 전달합니다.

 

script 영역의 handleClick() 함수를 다음 소스 코드로 수정하면, TypeError 없이 정상적으로 동작합니다.

const handleClick = (param) => {
  isInputElementView = param;
  if(param === true) {
    tick().then(() => inputBind.focus()); // DOM 적용 후 포커싱 처리
  }
}

예제 2. async와 await 함께 사용

위에서 보여준 문제점은 then() 메서드를 사용하지 않고 async와 await 키워드를 사용하여 해결할 수 있습니다.

const handleClick = async (param) => {
  isInputElementView = param;
  await tick(); // DOM 적용될 때까지 기다립니다.
  if(param === true) {
    inputBind.focus(); 
  }
}
  1. handleClick() 함수에 async 키워드를 적용합니다.
  2. 변수 isInputElementView의 값을 변경합니다.
  3. 변수 isInputElementView의 값이 변경되면 await tick() 함수를 호출합니다.
  4. tick() 함수의 실행이 끝났다는 의미는 컴포넌트 또는 DOM 요소가 DOM에 반영되었다는 의미이므로 input 태그를 포커싱 처리합니다.
반응형

댓글