Почему этот объект является прокси только тогда, когда поле страницы равно 1?

Действия по воспроизведению:

  1. Откройте репродукцию

  2. Откройте консоль браузера

  3. При запуске проекта возникают ошибки:

    Uncaught (in promise) DOMException: Failed to execute 'put' on 'IDBObjectStore': #<Object> could not be cloned.
    

    Почему этот объект является прокси только тогда, когда поле страницы равно 1?

    Это происходит потому, что IndexedDB не может сериализовать и сохранить прокси-объект, которым в данном случае является pagination.

    Но...

  4. Если вы нажмете кнопку «Далее», нумерация страниц изменится с {"page":1,"size":5} на {"page":2,"size":5}, и IndexedDB сохранит объект без проблем!

  5. Еще более странно: если нажать кнопку «Назад», она изменится с page:2 на page:1, и ошибка снова здесь!

Почему этот объект является прокси только тогда, когда поле страницы равно 1?

Почему первая страница является прокси-объектом, а следующие страницы — нет?

🤔 А знаете ли вы, что...
Svelte - это инновационный фронтенд-фреймворк, разработанный на языке JavaScript.


100
1

Ответ:

Решено

В этом нет ничего странного и странного!

Как уже упоминалось в моем комментарии, 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, поэтому обязательно обновляйте свойства объекта, а не переопределяйте весь объект.