Skip to content

Кешированные модели

Используйте кеш моделей, когда размонтирование компонента не должно уничтожать его модель.

Это полезно для чатов, вкладок редактора, медиаплееров, предпросмотров и экранов деталей, которые должны открываться в прежнем состоянии. Кеш — это еще и решение о жизненном цикле: модель останется в памяти, пока вы явно не удалите ее или не очистите кеш.

Выбор key

Кешированные модели хранятся по key внутри scope. Для чата key может быть chatId. Для вкладок редактора — id документа. Key должен описывать вещь, к которой пользователь ожидает вернуться.

tsx
const chatCache = createModelCache<string, Props, ChatModel>();

export const ChatPanel = component({
  cache: chatCache,
  key: (props: Props) => props.chatId,
  model: createChatModel,
  view({ model }) {
    return <div>{model.messages.items.join(", ")}</div>;
  },
});

Когда ChatPanel размонтируется, кешированная модель останется живой. Когда тот же key снова появится в том же scope, React получит существующую модель вместо создания новой.

Загрузка в модели

Модель может использовать mounted, чтобы загрузить данные при первом появлении:

tsx
function createChatModel({ key, mounted }: ModelContext<Props, string>) {
  const messages = store({ items: [] as string[] });
  const loadFx = effect(async (chatId: string) => [`loaded:${chatId}`]);

  reaction({
    on: mounted,
    run() {
      void loadFx(key);
    },
  });

  return { loading: loadFx.$pending, messages };
}

Для кешированных моделей важно решить, должен ли mounted перезагружать данные каждый раз при возвращении view или только при первом создании модели. Если перезагрузка дорогая, заведите стор вроде loaded и проверку в реакции.

Осознанное удаление

Кеш меняет память на непрерывность. Удаляйте модель, когда пользователь окончательно закрыл чат, вкладку, плеер или предпросмотр.

ts
chatCache.delete("support", appScope);
chatCache.clear(appScope);

Удаление кешированной модели вызывает dispose ее владельца, поэтому реакции и функции очистки, зарегистрированные внутри модели, тоже отвязываются.