языком + решение
💁♂️ Как это бывает
Порой вам нужно передать уникальные данные между несколькими страницами или компонентами.
Первое, что приходит в голову — использовать стор. Через него легко передавать данные, а подписка позволяет синхронизировать состояние и реагировать на изменения.
🤔 В чём опасность?
- Вы создаёте стор в js файле и импортируете его там, где необходимо.
- Что-то мутирует стор. Это вызывает обновление данных везде, где вы его используете.
— Мы часто так делаем на клиенте и пока всё в порядке. Но что если вам нужно передать данные на сервере?
Вы захотели поменять лэйаут страниц для авторизированного посетителя:
- Импортируете стор в load функцию и в экшн авторизации;
- Авторизируте посетителя;
- Отмечаете новое состояние в сторе;
- Load функция реагирует на изменения и выводит лэйаут авторизированного посетителя;
— Поздравляю, вы только что показали всем посетителям, что они авторизированны!
🎉🎉🎉
😳 Стоп, а что произошло?
Экспортируя стор из js файла вы создаёте ESM модуль. ESM модуль — синглтон. То есть он импортируется один раз и используется везде, где вы его импортируете.
→ подробнее на русском
Таким образом данные шарятся между компонентами. А использование подписок позволяет реагировать на изменения.
👀 Ну и что?
SvelteKit на сервере — это один процесс. Он обрабатывает запросы от всех посетителей и хранит своё состояние пока вы его не перезапустите.
Стор для всех запросов от посетителей будет использоваться один и тот же
Когда вы поменяете состояние стора для одного посетителя — оно сменится у всех.
🌚🌚🌚
✅ Как правильно передать состояние?
Для этого в серверных функциях вам доступен параметр locals. В него можно записать данные.
→ см. пример использования
Используйте его в load функции и передавайте данные дальше в компоненты через data-параметры.
А поскольку параметр locals используется в load функции, его изменения вызовут инвалидацию данных, что перезапустит load функцию и передаст новые данные странице.
——————
👉 Пример использования
Я написал простой пример использования стора и параметра locals для синхронизации состояния.
→ см. на stackblitz
Откройте одновременно несколько вкладок с приложением и посмотрите как по разному работают эти способы:
👎 Стор синхронизируется между вкладками после их перезагрузки и сохранит своё состояние.
Этого быть не должно, так как каждая вкладка — это изолированное окружение.
→ Чтобы сбросить состояние используйте reset или перезапустите приложение в консоли.
🤟 Параметр locals отобразится только в одной вкладке, а после презагрузки вкладки — обнулится. Это ожидаемое поведение.
Таким образом другие посетители не увидят смены состояния приложения.
#svelte #svelte_stores #svelte_gudes
да со сторами беда... но без них никуда
тут к слову есть нюанс - рендринг проходит атомарно так что если вы вначале рендрингда перезаписываете сторы то всё будет хорошо
Это достаточно искусственный пример, никто так не делает авторизацию. Лучше не придумал как просто показать ошибку использования сторов.
Может у locals есть какие-то другие преимущества по сравнению со сторами? Кэширование, например? Замечено, что если в load записывать в стор и устанавливать хедер stale-while-revalidate - ничего не происходит. Может с locals оно начнет работать
согласен - сейчас полез перепроверять и вроде везде я либо явно каждый раз перезаписываю стор из начальных данных либо со стором работаю чоже только в браузере. Но это конечно геморойно.
Кэширование устанавливается заголовком cache-control через setHeaders: load({ setHeaders }) { setHeaders({ age: […], 'cache-control': […] }); } → см. тут про кеширование
О, классика (с next.js та же проблема), реатом решает это тем что все атомы работают исключительно в выделенном контексте, который нужно в руте засетапить еще.
Обсуждают сегодня