Исправление ошибок

Основные ошибки

store: undefined is used to skip updates. To allow undefined as a value provide explicit { skipVoid: false } option

Эта ошибка сообщает вам о том, что вы пытаетесь передать в ваш стор значение undefined, что, возможно, является некорректным поведением.

Если вам действительно нужно передать ваш стор значение undefined, то вам надо вторым аргументом в createStore передать объект со свойством skipVoid: false.

const $store = createStore(0, {
  skipVoid: false,
});

serialize: One or more stores dont have sids, their values are omitted

До версии 23.3.0

До версии 23.3.0 эта ошибка также известна как: There is a store without sid in this scope, its value is omitted.

Эта ошибка часто встречается при работе с SSR, она связана с тем, что у вашего стора отсутствует sid (stable id), который необходим для корректной гидрации данных с сервера на клиент. Чтобы исправить эту проблему вам нужно добавить этот sid.
Сделать это вы можете несколькими способами:

  1. Использовать babel или SWC плагин, который сделает все за вас

  2. Или добавить sid в ручную, передав во второй аргумент createStore объект со свойством sid:

    const $store = createStore(0, {
      sid: "unique id",
    });
    

Более подробно про sid, как это работает и зачем это нужно.

scopeBind: scope not found

Эта ошибка случается когда скоуп потерялся на каком-то из этапов выполнения и scopeBind не может связать событие или эффект с нужным скоупом выполнения.
Эта ошибка могла быть вызвана:

  1. Вы используете режим работы ‘без скоупа’ и у вас их нет в приложении
  2. Ваши юниты были вызваны вне скоупа

Возможные решения:

  1. Используйте scopeBind внутри эффектов:

    const event = createEvent();
    
    // ❌ - не вызывайте scopeBind внутри колбеков
    const effectFx = createEffect(() => {
      setTimeout(() => {
        scopeBind(event)();
      }, 1111);
    });
    
    // ✅ - используйте scopeBind внутри эффекта
    const effectFx = createEffect(() => {
      const scopeEvent = scopeBind(event);
    
      setTimeout(() => {
        scopeEvent();
      }, 1111);
    });
    
  2. Ваши юниты должны быть вызваны внутри скоупа:

    • При работе с фреймворком используйте useUnit
    • Если у вас происходит вызов события или эффекта вне фреймворка, то используйте allSettled и передайте нужный scope в аргумент

Если того требует ваша реализация, а от ошибки нужно избавиться, то вы можете передать свойство safe:true во второй аргумент метода.

const scopeEvent = scopeBind(event, {
  safe: true,
});

Частые проблемы

sample.fn не сужает тип, который приходит из sample.filter

Частая проблема с типизацией sample происходит когда мы делаем проверку в filter на что-то, но не получаем необходимый тип в fn.

Исправление этой проблемы.

Мое состояние не изменилось

Скорее всего вы работаете со скоупами и в какой-то момент активный скоуп потерялся и ваш юнит выполнился в глобальной области.
Вы можете найти больше информации об этом тут. Это происходит при передаче юнитов (события или эффекты) в колбэк внешних функций, таких как:

  • setTimeout/setInterval
  • addEventListener
  • webSocket и др.

Чтобы исправить эту проблему привяжите ваше событие или эффект к текущему скоупу при помощи scopeBind:

const event = createEvent();

// ❌ - так у вас событие вызовется в глобальной области видимости
const effectFx = createEffect(() => {
  setTimeout(() => {
    event();
  }, 1000);
});

// ✅ - так у вас будет работать как ожидаемо
const effectFx = createEffect(() => {
  const scopeEvent = scopeBind(event);
  setTimeout(() => {
    scopeEvent();
  }, 1000);
});

Использование юнитов без useUnit

Возможно вы используете события или эффекты во фреймворках без использования хука useUnit, что может также повлиять на неправильную работу со скоупами.
Чтобы исправить это поведение передайте нужный юнит в useUnit хук и используйте возвращаемое значение:

import { event } from "./model.js";

const Component = () => {
  return <button onClick={() => event()}></button>;
};

Что такое потеря скоупа и почему это происходит

Не нашли ответ на свой вопрос ?

Если вы не нашли ответ на свой вопрос, то вы всегда можете задать сообществу:

Перевод поддерживается сообществом

Документация на английском языке - самая актуальная, поскольку её пишет и обновляет команда effector. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.

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

Соавторы