Вопросы по использованию магазинов Svelte с древовидным вложенным объектом

Как использовать Svelte store с древовидным вложенным объектом? Из этого ответа:

Примечание: привязки работают, только если это одна и та же переменная. То есть вы не можете поместить связанную переменную в промежуточную переменную и заставить Svelte отслеживать эту привязку.

Это и мое собственное тестирование, похоже, подразумевают, что нельзя реактивно обновить вложенное хранилище (обновить хранилище и получить это обновление состояния) из сценария, внешнего по отношению к компоненту Svelte. Насколько я понимаю, единственный способ сделать это - вручную вызвать store.update() в скрипте после внесения изменений в хранилище. Это правильно?

Я хочу реорганизовать свой код: код моего основного компонента становится слишком громоздким, и я хотел бы ввести больше компонентов и, возможно, оставить функции обновления состояния в .js файлах вне компонентов для повторного использования.

Некоторые вопросы по производительности:

  1. Будет ли выполнение обновлений вручную менее производительным, чем автоматическое выполнение Svelte?
  2. Мое приложение должно обрабатывать довольно большой вложенный магазин с сотнями веток. В приведенном выше ответе предлагается создать вложенное хранилище с ветвями, обернутыми в их собственные хранилища. Могут ли сотни (вложенных) хранилищ значительно увеличить объем памяти, занимаемый приложением, по сравнению с использованием одного хранилища?

person noos    schedule 02.06.2021    source источник


Ответы (1)


As far as I can see, the only way to do it is to manually call store.update() in the script after making changes to the store. Is this correct?

Это почти правильно. update получает функцию, которой передается текущее значение, и ожидает следующего значения. Если вы управляете своим состоянием снаружи, а затем передаете его в магазин, позвоните set.

const myNewValue = doStuff(oldValue);
store.set(myNewValue);

vs

store.update(oldValue => doStuff(oldValue));

Изменение значения хранилища напрямую (например, storeValue.property = 1) не приведет к запуску обновления, вы должны явно обновить хранилище для Svelte, чтобы сделать переменные недействительными. Я также предлагаю обернуть эти манипуляции методами в магазине, которые помогут вам отслеживать, что и откуда обновляется, когда код становится больше.

store.js:

const _store = writable(initialValue);

function doASpecificModification(foo) {
  _store.update(oldValue => { ... });
}

export const store = {
  subscribe: _store.subscribe,
  doASpecificModification
};

Would doing manual updates be less performant than what Svelte does automatically?

Если под «автоматически» вы имеете в виду синтаксис $store = newValue: он сокращается до store.set(newValue), значит, нет никакой разницы. Более того, Svelte будет повторно отображать только те части, в которых вы подписаны на магазин, поэтому производительность не должна быть проблемой (также см. Следующий раздел).

My app needs to handle a pretty big nested store, with hundreds of branches. In the answer linked above, it is proposed to create a nested store, with branches wrapped in their own stores. Would having hundreds of (nested) stores significantly increase the memory footprint of the app compared to just using a single store?

Что касается производительности: вероятно, лучше сделать обновления более детализированными, либо обернув ветки в их собственных магазинах, либо имея одно большое хранилище, но с выбранными фрагментами хранилища таким образом, чтобы они не запускали обновление, если их часть не менялась (в этом вам помогут производные магазины). Если эти ветки не связаны друг с другом, я предлагаю разделить их (также, чтобы избежать большого двоичного объекта; мне не нравится этот Redux-style-keep-all-in-one-object). Объем памяти здесь не имеет значения.

person dummdidumm    schedule 02.06.2021
comment
Спасибо за Ваш ответ! О update и set: в моем случае реквизиты, которые рекурсивно передаются вниз, являются объектами (с их свойствами, формирующими состояние), что означает, что я могу передать их (ссылку) другим скриптам и изменить их свойства там. Это фактически изменяет магазин; изменение просто не распространяется где-либо еще, потому что это не выполняется с помощью синтаксиса $ или методов хранения. Чтобы распространить изменение, я могу просто позвонить store.update(x => x). Могу ли я улучшить что-то в своем подходе? Ветви могут быть связаны, поэтому я рассмотрю их моделирование с помощью производных хранилищ. - person noos; 02.06.2021
comment
Я обновил свой ответ на первый вопрос. Резюме: нет другого способа, кроме явного вызова функции обновления / установки магазина. - person dummdidumm; 03.06.2021