Inertia.js v3.7.0 надає компоненту <Form> два способи перервати відправку, яка все ще виконується: метод cancel, який ви викликаєте самостійно, та атрибут cancelOnUnmount, що спрацьовує, коли форма покидає сторінку. Реліз також додає реактивне значення polling до usePoll і припиняє скасування фонових асинхронних запитів при навігації.
Основні зміни
cancelOnUnmount на <Form> перериває відправку при розмонтуванні форми
cancel тепер доступний через slot props, ref та контекст <Form>
usePoll повертає значення polling разом з start та stop
- Once props зберігають своє значення через instant visit
- Навігація більше не скасовує асинхронні запити, спрямовані на інші сторінки
- Виправлення для React
back_forward відновлень, ідентичності replaceProp prop та збою розмонтування <Form>
Скасування відправки при розмонтуванні форми
Відправка, яка виконується, переживає компонент, що її розпочав. Перехід на іншу сторінку випадково скасовує її, але лише як побічний ефект наступного синхронного запиту, що перериває попередній візит. Закриття модального вікна нічого не перериває, тому повільне завантаження аватара, яке користувач вважав покинутим, все одно завершується і обробляється на сервері.
Компонент <Form> тепер приймає атрибут cancelOnUnmount, який скасовує запит при розмонтуванні форми:
<Form action="/avatar" method="post" cancel-on-unmount>
<input type="file" name="avatar" />
<button type="submit">Upload</button>
</Form>
Той самий атрибут існує в адаптерах React та Svelte як cancelOnUnmount. За замовчуванням він встановлений у false, тому існуючі форми зберігають поточну поведінку дозволу завершення запиту.
Відправка, яка вже успішно завершилася, залишається недоторканою. Щоб це працювало, pull request також змінив основну обробку запитів, так що функція, передана в onCancelToken, стає no-op після отримання відповіді. Скасування на цьому етапі все одно не могло б нічого зупинити, оскільки сторінка вже оновлюється, але воно викликало подію onCancel після onSuccess. Це важливо для типового шаблону модального вікна, де onSuccess закриває діалог: форма розмонтується через мить після надходження відповіді, і без захисту хук розмонтування скасував би запит, який вже завершився.
Метод cancel на компоненті Form
Компонент <Form> завжди використовував useForm() внутрішньо, але ніколи не надавав метод cancel цієї форми, тому не було чистого способу підключити кнопку скасування при великому завантаженні. cancel тепер доступний через slot props, ref компонента та контекст форми в усіх трьох адаптерах:
<Form action="/avatar" method="post" v-slot="{ processing, cancel }">
<input type="file" name="avatar" />
<button type="submit" :disabled="processing">Upload</button>
<button v-if="processing" type="button" @click="cancel">Cancel</button>
</Form>
Адаптер React передає його через render prop таким же чином:
<Form action="/avatar" method="post">
{({ processing, cancel }) => (
<>
<input type="file" name="avatar" />
<button type="submit" disabled={processing}>Upload</button>
{processing && (
<button type="button" onClick={cancel}>Cancel</button>
)}
</>
)}
</Form>
usePoll повідомляє про стан виконання
Полінг з usePoll повертав start та stop, і нічого більше. Рендеринг перемикача паузи та відновлення означав підтримку власного булевого значення в синхронізації з цими двома викликами та необхідність ініціалізувати його з опції autoStart. Хук тепер повертає реактивне значення polling, яке відстежує це для вас:
import { usePoll } from '@inertiajs/vue3'
const { start, stop, polling } = usePoll(2000)
<template>
<button v-if="polling" @click="stop">Pause updates</button>
<button v-else @click="start">Resume updates</button>
</template>
Воно відображає, чи працює поллінг, а не чи виконується запит у даний момент, тому залишається true у проміжках між запитами. Початкове значення береться з autoStart, який за замовчуванням true. У Vue значення є Ref<boolean>, у React це useState, а адаптер Svelte перемістив usePoll у файл .svelte.ts, щоб він міг підтримувати значення за допомогою $state. Ця остання зміна означає, що користувачі Svelte, які деструктурують повернене значення, втрачають реактивність, тому зберігайте об'єкт і читайте poll.polling.
Once Props переживають Instant Visits
Once props в Inertia розв'язуються один раз, а потім запам'ятовуються на клієнті, тому наступні сторінки, які включають той самий prop, повторно використовують значення замість того, щоб знову запитувати сервер обчислювати його. Instant visits - це інша сторона медалі: надання <Link> або router.visit() цільового імені component негайно міняє цю сторінку, поки справжній запит виконується у фоновому режимі.
Разом вони втрачали дані. Сторінка-заповнювач була побудована зі спільних props та всього, що надав візит, що скинуло як значення once prop, так і його реєстрацію. Prefetch, який вже заявив prop, потім розв'язувався без нічого для відновлення, і prop повертався порожнім.
Маршрутизатор тепер копіює кожен запам'ятований once prop та його запис у реєстрі на сторінку-заповнювач перед обміном, якщо тільки візит не надав власне значення для цього prop, у такому випадку вхідне значення перемагає.
Асинхронні візити більше не скасовуються навігацією
Inertia скасовує запити, що виконуються, коли ви переходите на іншу сторінку, що є бажаною поведінкою для відкладених props та часткових перезавантажень, які належать сторінці, яку ви покидаєте. Перевірка була занадто широкою. Вона також знищувала явні асинхронні візити, спрямовані на інші сторінки, тому подвійне клацання асинхронного <Link> або навігація в інше місце під час виконання асинхронного запиту скасовували попередній.
Скасування тепер збігається з origin та path запиту, і скасовує лише запити, спрямовані на сторінку, від якої здійснюється навігація. Відкладені props, часткові перезавантаження, router.reload() та поли всі націлені на поточну сторінку і скасовуються як раніше, тоді як фонові асинхронні візити на інші сторінки залишаються завершуватися.
Виправлення помилок
Три виправлення завершують реліз:
-
React зберігав застарілі props після дублювання вкладки. Chrome та Firefox повідомляють про дубльовану вкладку як навігацію back_forward, тому Inertia відновлює сторінку зі стану історії, включаючи відкладені props. Адаптер React відкидав цю відновлену сторінку при завантаженні, припускаючи, що перше оновлення після монтування завжди повторює сторінку, відрендерену сервером, що залишало usePage() застряглим на початкових props. Адаптер тепер пропускає лише повторний рендеринг початкової сторінки та утримує оновлення, яке надходить до монтування програми, щоб можна було його відтворити. Vue та Svelte не постраждали.
-
replaceProp() надавав кожному prop нову ідентичність. Побудова нового об'єкта props з глибоким клонуванням означала, що replaceProp, appendToProp та prependToProp повторно рендерили мемоізовані компоненти, які споживають непов'язані props, і коштували повного клонування на виклик. Immutable set з урахуванням шляху тепер копіює лише контейнери вздовж шляху, відповідаючи тому, як часткові перезавантаження вже обробляють недоторкані props.
-
<Form> міг викидати помилку при розмонтуванні. Адаптер React відкладає свою перевірку dirty-state через startTransition, яка не скасовується при розмонтуванні, тому подія input або change, викликана безпосередньо перед навігацією, могла виконати new FormData(null) і викинути TypeError. getFormData тепер повертає порожній FormData, коли елемент форми зникає.
Встановлення
Оновіть через свій пакетний менеджер, використовуючи адаптер, на якому працює ваш додаток:
npm install @inertiajs/vue3@^3.7.0
# або @inertiajs/react, @inertiajs/svelte