Действия по воспроизведению:
Откройте репродукцию
Откройте консоль браузера
При запуске проекта возникают ошибки:
Uncaught (in promise) DOMException: Failed to execute 'put' on 'IDBObjectStore': #<Object> could not be cloned.
Это происходит потому, что IndexedDB не может сериализовать и сохранить прокси-объект, которым в данном случае является pagination
.
Но...
Если вы нажмете кнопку «Далее», нумерация страниц изменится с {"page":1,"size":5}
на {"page":2,"size":5}
, и IndexedDB сохранит объект без проблем!
Еще более странно: если нажать кнопку «Назад», она изменится с page:2
на page:1
, и ошибка снова здесь!
Почему первая страница является прокси-объектом, а следующие страницы — нет?
🤔 А знаете ли вы, что...
Svelte - это инновационный фронтенд-фреймворк, разработанный на языке JavaScript.
В этом нет ничего странного и странного!
Как уже упоминалось в моем комментарии, svelte 5 изменил способ работы реактивности с использованием сигналов. В svelte 5 реактивность теперь по умолчанию вложена с использованием прокси.
Внутри Pagination.svelte
происходит то, что вы определили привязываемую опору
let {
conditions,
pagination = $bindable()
}: Props = $props();
Если вы создадите журнал консоли прямо под этим, вы увидите, что pagination
заворачивается в прокси.
Библиотека, которую вы используете (@tanstack/svelte-query
), вероятно, еще несовместима со svelte 5.
Следующий код объясняет, почему изначально свойство pagination
является прокси, но после смены страницы оно больше не является прокси.
Вы перезаписываете весь объект, а не просто обновляете его свойства.
// Dont do this in svelte 5, this causes it to lose its `proxied` state.
pagination = { ...pagination, page: pagination.page + 1 };
Это был способ svelte 4 сказать, что что-то изменилось. В svelte 5 это станет
// Do this in svelte 5
pagination.page = pagination.page + 1;
Использование «старого» метода svelte 4 не будет правильно распространять изменения в вашем приложении в svelte 5, поэтому обязательно обновляйте свойства объекта, а не переопределяйте весь объект.