Отмена отдельного запроса в Inertia
Скажем, строка поиска шлёт
отдельный запрос на каждый
символ. Пока человек печатает
быстро, старые ответы могут
прийти позже новых и испортить
список под полем. Нужно
оборвать именно текущий
запрос хелпера, не трогая
другие визиты router,
которые могут идти параллельно.
У экземпляра useHttp
есть метод cancel.
Он прерывает только тот запрос,
который этот экземпляр
сейчас выполняет. Вызов
перед новой отправкой
гарантирует, что устаревший
ответ не обновит экран.
Для независимых действий
удобно завести несколько
экземпляров хелпера: у каждого
своё processing и своя
отмена.
Давайте отдадим страницу и медленный JSON-поиск:
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
Route::get('/posts/search', function () {
return Inertia::render('Posts/Search');
});
Route::get('/api/posts/search', function (Request $request) {
sleep(1);
return response()->json([
'hits' => ['Result for query'],
]);
});
?>
Давайте отменим предыдущий запрос перед каждым новым и выведем последние hits:
<script setup>
import { ref } from 'vue'
import { useHttp } from '@inertiajs/vue3'
const http = useHttp({
query: '',
})
const hits = ref([])
function runSearch() {
http.cancel()
http.get('/api/posts/search', {
onSuccess: (data) => {
hits.value = data.hits
},
})
}
</script>
<template>
<h1>Search</h1>
<input v-model="http.query" @input="runSearch" />
<ul>
<li v-for="item in hits" :key="item">
{{ item }}
</li>
</ul>
</template>
Сделайте страницу WorkerLookup с быстрым вводом имени, чтобы каждый новый символ отменял предыдущий отдельный запрос и список не залипал на старом ответе.