요청 관찰: useWatcher
페이징, 데이터 필터링, 퍼지 검색 등 데이터 변경 시 다시 요청해야 하는 일부 시나리오에서는
useWatcher를 사용하여 지정된 상태 변경을 모니터링하고 즉시 요청을 보낼 수 있습니다.
할일 항목 검색을 예로 들어보겠습니다. 검색창에서 옵션을 변경하고 할 일 목록이 어떻게 변경되는지 확인하세요.
<select v-model="userId">
<option :value="1">User 1</option>
<option :value="2">User 2</option>
<option :value="3">User 3</option>
</select>
const userId = ref(1);
// 메소드 인스턴스 생성
const filterTodoList = userId => {
return alovaInstance.Get(`/users/${userId}/todos`);
};
const { loading, data, error } = useWatcher(
// 메소드 인스턴스를 반환하는 함수로 설정되어야 합니다.
() => filterTodoList(userId.value),
// 모니터링되는(monitored) 상태 배열, 이러한 상태 변경은 요청을 트리거합니다.
[userId]
);
const currentPage = ref(1);
// 메소드 인스턴스 생성
const getTodoList = currentPage => {
return alovaInstance.Get('/todo/list', {
params: {
currentPage,
pageSize: 10
}
});
};
const { loading, data, error } = useWatcher(
// 첫 번째 매개 변수는 메소드 인스턴스 자체가 아니라 메소드 인스턴스를 반환하는 함수입니다.
() => getTodoList(currentPage.value),
// 감시된(watched) 상태 배열, 이러한 상태 변경은 요청을 트리거합니다.
[currentPage],
{
// ⚠️useWatcher 호출은 기본적으로 트리거되지 않습니다. useRequest와의 차이점에 유의하세요.
// 처음에 1페이지의 데이터를 얻으려면 immediate를 true로 수동으로 설정하세요.
immediate: true
}
);
useWatcher는 요청을 즉시 보낼 수도 있지만(immediate: true)
useWatcher의immediate속성은 기본값이false라는 점에 유의해야 합니다.
일반적으로 우리는 자주 발생하는 이벤트 수준에서 디바운스 코드를 작성합니다.
우리는 요청 수준(level)에서 디바운스 기능을 구현했습니다. 즉, 더 이상 퍼지 검색 기능에서 디바운스를 직접 구현할 필요가 없으며 사용법도 매우 간단합니다.
디바운스가 무엇인가요?
디바운스(Debounce)는 이벤트가 트리거된 후 함수가 n초 내에 한 번만 실행될 수 있음을 의미합니다. 이벤트 발생 후 n초 이내에 다시 이벤트가 발생하면, 함수 지연 실행 시간이 다시 계산됩니다. (여기에서는 스로틀링과 구분하면, 스로틀링(Throttling)이란 이벤트가 발생한 후 일정 시간 내에 해당 이벤트가 다시 발생하지 않는다는 의미입니다.)
debounce를 숫자로 설정하면 모든 감시 상태의 바운스 방지(anti-bounce) 시간을 밀리초(milliseconds) 단위로 나타냅니다.
const { loading, data, error } = useWatcher(
() => filterTodoList(keyword, date),
[keyword, date],
{ debounce: 500 }
);
키워드 및 날짜 중 하나 이상의 상태(states)가 변경되면 요청이 500ms 후에 전송된다는 것을 의미합니다.
많은 시나리오에서는, 텍스트 상자의 onInput에 의해 트리거된 상태 변경과 같이, 자주 변경되는 특정 관찰 상태만 디바운싱하면 됩니다.
const { loading, data, error } = useWatcher(
() => filterTodoList(keyword, date),
[keyword, date],
{ debounce: [500, 0] }
// 또는 debounce: [500]
);
감시 상태 배열 순서대로 디바운스 시간을 설정합니다. 0 또는 전달되지 않으면 디바운스가 없음을 의미합니다.
여기서 감시 상태의 순서는 [keyword, date]이고, 디바운스 배열 설정은 [500, 0]으로,
keyword의 디바운스만 별도로 설정한다는 의미입니다.
감시 상태가 변경될 때 요청을 보내지 않으려는 경우도 있습니다. Hook 구성의 sendable 속성을 사용하여 감시 상태가 변경될 때 요청을 보낼지 여부를 제어할 수 있습니다. sendable 속성은 매개변수가 AlovaEvent 이벤트 객체인 함수입니다.
send 함수에 의해 전달된 매개변수로 구성된 sendArgs 배열과 현재 요청의 메소드 인스턴스를 포함하며,
함수는 truthy/falsy 값을 반환하여 상태가 변경될 때 요청을 트리거해야 하는지 여부를 결정합니다(기본값은 true). 오류를 던지면 요청을 트리거하지 않는다는 의미도 됩니다.
useWatcher(
() => getTodoList($currentPage),
[state],
{
sendable: ({ sendArgs, method }) => {
return state === 1; // state가 1일 때만 요청 보내기
}
}
);
때때로 useWatcher가 감시하는 상태가 계속해서 변경되어 연속적인 요청이 시작되는 경우,
후자의 요청은 이전 요청보다 먼저 응답을 받지만, 이전 요청이 응답을 받으면 후자 요청의 응답을 덮어씁니다. 결과적으로 상태(state)일치하지 않는 응답을 받습니다;
예를 들어, state 상태가 변경되어 요청 1이 발행되고(issued),
요청 1이 응답하지 않았을 때 state 값이 변경되어 요청 2가 발행됩니다.
요청 2 이후에 요청 1이 반환되면 최종 응답 데이터는 요청 1에 유지됩니다.
- 요청 1를 트리거하기 위한 상태 변경
- 요청 2를 트리거하기 위한 상태 변경
- 요청 2가 먼저 응답
- 그런 다음 요청 1이 응답
- 요청 2의 응답을 덮어씀.
useWatcher(
() => getTodoList($currentPage),
[state],
{
abortLast: true // 응답하지 않는 마지막 요청을 중단할지 여부 (기본값 true)
}
);
abortLast의 기본값은true입니다.
false로 변경할 경우 상태 및 응답 불일치 문제가 발생할 수 있습니다.